Программирование >>  Преобразование значений null 

1 ... 18 19 20 [ 21 ] 22 23 24 ... 219


Поэтому я указал NULL, чтобы обратить ваше внимание на объединение в подзапросе, а не на элементы списка SELECT.

Извлечение из таблицы строк, для которых нет соответствия в другой таблице

Задача

В одной из двух таблиц, имеющих общие ключи, требуется найти строки, которых нет в другой таблице. Например, необходимо определить, в каком отделе нет служащих. Результирующее множество должно быть таким:

DEPTNO DNAME LOC

40 OPERATIONS BOSTON

Поиск отдела, в котором работает каждый из служащих, требует проведения операции эквиобъединения таблиц EMP и DEPT по столбцу DEPTNO. Столбец DEPTNO представляет общее значение для обеих таблиц. К сожалению, эквиобъединение не даст информацию о том, в каком отделе нет служащих, поскольку в результате этой операции будут возвращены все строки, удовлетворяющие условию объединения. А нам нужны только те строки таблицы DEPT, которые не удовлетворяют условию объединения.

Данная задача несколько отличается от той, что была поставлена в предыдущем рецепте, хотя на первый взгляд может показаться такой же. Разница в том, что в предыдущем рецепте формировался только список номеров отделов, не представленных в таблице EMP. Однако, используя настоящий рецепт, можно извлечь и другие столбцы таблицы DEPT и возвратить не только номера отделов.

Решение

Извлеките все строки одной таблицы и строки другой таблицы, которые могут иметь или не иметь соответствия по общему столбцу. Затем оставьте только те строки, которые не имеют соответствия.

DB2. MySQL, PostgreSQL, SQL Server

Используйте внешнее объединение и фильтр для значений NULL (ключевое слово OUTER (внешний) является необязательным):

1 select d.*

2 from dept d left outer join emp e

3 on (d.deptno = e.deptno)

4 where e.deptno is null



Oracle

Предыдущее решение подойдет пользователям, работающим с Oracle 9i Database и более поздними версиями. В качестве альтернативы может использоваться собственный синтаксис Oracle для внешнего объединения:

1 select d.*

2 from dept d, emp e

3 where d.deptno = e.deptno (+)

4 and e.deptno is null

Этот собственный синтаксис (обратите внимание на использование + в скобках) - единственный доступный в Oracle 8i Database и более ранних версиях синтаксис внешнего объединения.

Обсуждение

Данное решение обеспечивает внешнее объединение с последующим возвращением только тех строк, которые не имеют соответствия. Операции такого рода иногда называют антиобъединением (anti-join). Чтобы лучше понять принцип антиобъединения, рассмотрим результирующее множество, получаемое без фильтрации значений NULL:

select e.ename, e.deptno as emp deptno, d.* from dept d left join emp e on (d.deptno = e.deptno)

ENAME

EMP DEPTNO

DEPTNO

DNAME

SMITH

RESEARCH

DALLAS

ALLEN

SALES

CHICAGO

WARD

SALES

CHICAGO

JONES

RESEARCH

DALLAS

MARTIN

SALES

CHICAGO

BLAKE

SALES

CHICAGO

CLARK

ACCOUNTING

NEW YORK

SCOTT

RESEARCH

DALLAS

KING

ACCOUNTING

NEW YORK

TURNER

SALES

CHICAGO

ADAMS

RESEARCH

DALLAS

JAMES

SALES

CHICAGO

FORD

RESEARCH

DALLAS

MILLER

ACCOUNTING

NEW YORK

OPERATIONS

BOSTON

Обратите внимание, в столбцах EMP.ENAME и EMP DEPTNO последней строки отсутствуют значения, потому что в 40-м отделе нет служащих. С помощью предиката WHERE в решении выбираются только строки со значением NULL в столбце EMP DEPTNO (таким образом, возвращаются только те строки DEPT, которым нет соответствия вEMP).



Независимое добавление объединений в запрос Задача

Имеется запрос, возвращающий требуемые результаты. Возникает необходимость в дополнительной информации, но при попытке получить ее теряются данные исходного результирующего множества. Например, необходимо получить имена всех служащих, местонахождение отделов, в которых они работают, и даты выдачи им премий. Для выполнения этой задачи существует таблица EMP BONUS со следующими данными:

select * from emp bonus

EMPNO RECEIVED

TYPE

7369 14-MAR-2005 7900 14-MAR-2005 7788 14-MAR-2005

Исходный запрос выглядит следующим образом:

select e.ename, d.loc from emp e, dept d where e.deptno=d.deptno

ENAME

SMITH

ALLEN

WARD

JONES

MARTIN

BLAKE

CLARK

SCOTT

KING

TURNER

ADAMS

JAMES

FORD

MILLER

DALLAS

CHICAGO

CHICAGO

DALLAS

CHICAGO

CHICAGO

NEW YORK

DALLAS

NEW YORK

CHICAGO

DALLAS

CHICAGO

DALLAS

NEW YORK

К этим результатам требуется добавить даты выдачи премии, но объединение с таблицей EMP BONUS приведет к тому, что будут возвращены только те строки, которые соответствуют служащим, получившим премию:

select e.ename, d.loc,eb.received

from emp e, dept d, emp bonus eb

where e.deptno=d.deptno

and e.empno=eb.empno



1 ... 18 19 20 [ 21 ] 22 23 24 ... 219

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика