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

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

Пример 18.14. Найти номера и названия отделов, название которых начинается со слов'Hardware'или'Software', а за ними (не обязательно непосредственно) следует последовательность десятичных цифр, предваряемых символом подчеркивания.

SELECT DEPT_NAME, DEPT_NO

FROM DEPT

WHERE DEPT_NAME SIMILAR TO

'(HARD|SOFT)WARE%\_[:DIGIT:]+' ESCAPE '\';

Пример 18.15. Найти номера и названия проектов, название которых не начинается с последовательности цифр.

SELECT DEPT_NAME, DEPT_NO

FROM DEPT

WHERE DEPT_NAME SIMILAR TO '[^1-9]+%';

18.2.7. Предикат exists

Предикат existsопределяется следующим синтаксическим правилом:

exists_predicate ::= EXISTS (query_expression)

Значением условия EXISTS (query_expression)являетсяtrueв том и только в том случае, когда мощность таблицы-результата выражения запросов больше нуля, иначе значением условия являетсяfalse.

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

Пример 18.16. Найти номера отделов, среди служащих которых имеются менеджеры проектов.

SELECT DEPT.DEPT_NO

FROM DEPT

WHERE EXISTS

(SELECT EMP.EMP_NO

FROM EMP

WHERE EMP.DEPT_NO = DEPT.DEPT_NO

AND EXISTS

(SELECT PRO.PRO_MNG

FROM PRO

WHERE PRO.PRO_MNG = EMP.EMP_NO));

Эту формулировку можно упростить, избавившись от самого вложенного запроса (пример 18.16.1):

SELECT DEPT.DEPT_NO

FROM DEPT

WHERE EXISTS

(SELECT EMP.EMP_NO

FROM EMP, PRO

WHERE EMP.DEPT_NO = DEPT.DEPT_NO

AND PRO.PRO_MNG = EMP.EMP_NO);

Далее заметим, что по смыслу предикатпредиката EXISTSсписок выборки во вложенном подзапросе является несущественным, и формулировку запроса можно изменить, например, следующим образом (пример 18.16.2):

SELECT DEPT.DEPT_NO

FROM DEPT

WHERE EXISTS

(SELECT *

FROM EMP, DEPT

WHERE EMP.DEPT_NO = DEPT.DEPT_NO

AND PRO.PRO_MNG = EMP.EMP_NO);

Запросы с предикатомEXISTSможно также переформулировать в виде запросов с предикатом сравнения (пример 18.16.3):

SELECT DEPT.DEPT_NO

FROM DEPT

WHERE (SELECT COUNT(*)

FROM EMP, DEPT

WHERE EMP.DEPT_NO = DEPT.DEPT_NO

AND PRO.PRO_MNG = EMP.EMP_NO ) >= 1;

Пример 18.17. Найти номера отделов, размер заработной платы служащих которых не превышает размер заработной платы руководителя отдела.FROM DEPT WHERE NOT EXISTS (SELECT * FROM EMP EMP1, EMP EMP2 WHERE EMP1.EMP_NO = DEPT.DEPT_MNG AND EMP2.DEPT_NO = DEPT.DEPT_NO AND EMP2.EMP_SAL > EMP1.EMP_SAL);

18.2.8. Предикат unique

Этот предикат позволяет сформулировать условие отсутствия дубликатов в результате запроса:

unique_predicate ::= UNIQUE (query_expression)

Результатом вычисления условия UNIQUE (query_expression)являетсяtrueв том и только в том случае, когда в таблице-результате выражения запросов отсутствуют какие-либо две строки, одна из которых является дубликатом другой. В противном случае значение условия естьfalse.

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

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

SELECT DEPT_NO

FROM DEPT

WHERE UNIQUE

(SELECT EMP_NAME, EMP_BDATE

FROM EMP

WHERE EMP.DEPT_NO = DEPT.DEPT_NO);

Возможна альтернативная, но более сложная формулировка этого запроса с использованием предикатаNOT EXISTS(пример 18.18.1):

SELECT DEPT_NO

FROM DEPT

WHERE NOT ESISTS

(SELECT *

FROM EMP, EMP EMP1

WHERE EMP1.EMP_NO <> EMP.EMP_NO

AND EMP.DEPT_NO = DEPT.DEPT_NO

AND EMP1.DEPT_NO = DEPT.DEPT_NO

AND EMP1.EMP_NAME = EMP.EMP_NAME

AND(EMP1.EMP_BDATE = EMP.EMP_BDATE

OR (EMP.EMP_BDATE IS NULL

AND EMP1.EMP_BDATE IS NULL)));

Если же ограничиться требованием уникальности имен служащих, то возможна следующая формулировка (пример 18.18.2):

SELECT DEPT_NO

FROM DEPT

WHERE (SELECT COUNT (EMP_NAME)

FROM EMP

WHERE EMP.DEPT_NO = DEPT.DEPT_NO) =

(SELECT COUNT (DISTINCT EMP_NAME)

FROM EMP

WHERE EMP.DEPT_NO = DEPT.DEPT_NO);