Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Базы данных.doc
Скачиваний:
114
Добавлен:
16.03.2016
Размер:
5.67 Mб
Скачать

Примеры запросов с использованием предиката null

На самом деле, в нашей формулировке запроса изпримера 18.6есть одна неточность. Если у некоторого служащего номер отдела неизвестен (значение столбцаEMP.DEPT_NOу соответствующей строки таблицы служащих является неопределенным), то бессмысленно вычислять средний размер зарплаты отдела этого служащего и находить размер зарплаты руководителя отдела. Формулировка изпримера 18.6приведет к правильному результату, но это неочевидно.138)Чтобы сделать формулировку более понятной (и, возможно, помочь системе выполнить запрос более эффективно), нужно воспользоваться предикатомIS NOT NULLи переписать запрос следующим образом:

Пример 18.7.

SELECT EMP_NO, EMP_NAME

FROM EMP

WHERE DEPT_NO IS NULL;

Пример 18.8. Найти номера и имена служащих, номер отдела которых неизвестен.

SELECT EMP_NO, EMP_NAME, EMP_SAL

FROM EMP

WHERE DEPT_NO IS NOT NULL AND

EMP_SAL BETWEEN

(SELECT AVG(EMP1.EMP_SAL)

FROM EMP EMP1

WHERE EMP.DEPT_NO = EMP1.DEPT_NO)

AND

(SELECT EMP1.EMP_SAL

FROM EMP EMP1

WHERE EMP1.EMP_NO =

( SELECT DEPT.DEPT_MNG

FROM DEPT

WHERE DEPT.DEPT_NO = EMP.DEPT_NO ) );

18.2.4. Предикат in

Предикат позволяет специфицировать условие вхождения строчного значения в указанное множество значений. Синтаксические правила следующие:

in_predicate ::= row_value_constructor [ NOT ]

IN in_predicate_value

in_predicate_value ::= table_subquery

| (value_expression_comma_list)

Строка, являющаяся первым операндом, и таблица-второй операнд должны быть одинаковой степени. В частности, если второй операнд представляет собой список значений, то первый операнд должен иметь степень 1. Типы данных соответствующих столбцов операндов должны быть совместимы.

Пусть Xобозначает строку-первый операнд, аS– множество строк второго операнда. Обозначим черезsстроку-элемент этого множества. Тогда по определению условиеX IN Sэквивалентно булевскому выражениюOR (X = s). Другими словами,X IN Sпринимает значениеtrueв том и только в том случае, когда во множествеSсуществует хотя бы один элементs, такой, что значением предикатаX = sявляетсяtrue.X IN Sпринимает значениеfalseв том и только том случае, когда для всех элементовsмножестваSзначением операции сравненияX = sявляетсяfalse. Иначе значением

138 Покажем это в развернутой форме. Пусть s – текущая строка таблицы EMP, просматриваемой в цикле внешнего запроса, и пусть s.DEPT_NO содержит неопределенное значение. Тогда для строки s условие первого подзапроса будет иметь вид NULL = EMP1.DEPT_NO, и значением этого условия будет unknown для любой строки таблицы EMP(EMP1), просматриваемой в цикле этого подзапроса. Поскольку unknown не является разрешающим условием, результирующая таблица подзапроса будет пуста, и агрегатная функция AVG выдаст значение NULL. По этому поводу значением условия внешнего запроса будет unknown, и строка s не войдет в результирующую таблицу.

условия X IN Sявляетсяunknown. Заметим, что для пустого множестваSзначениемX IN Sявляетсяfalse.

По определению условие X NOT IN SэквивалентноNOT (X IN S).