Многостолбцовые подзапросы

Квантифицированные подзапросы

Квантифицированными называют подзапросы, созданные с использованием кванторов: операторов ALL и EXISTS. Оператор ALL уже был описан ранее в этой лекции. Квантор EXISTS используется для определения того, вернул ли подзапрос хоть одну строку. Условие с EXISTS является истинным в случае, если подзапрос вернул непустое множество строк.

Пример: Найти всех служащих, у которых зарплата такая же, как у служащего по фамилии Ngao:

SELECT last_name

FROM s_emp one

WHERE EXISTS (SELECT *

FROM s_emp

WHERE salary=one.salary
AND last_name=’Ngao’);

Результат:

LAST_NAME

--------------

Ngao

Quick-To-See

Dumas

Здесь используется коррелированный квантифицированный подзапрос. Для каждой фамилии, которую выберет внешний запрос, подзапрос выбирает служащих с такой же зарплатой и фамилией Ngao. Если хоть одна такая строка найдется, значит, служащий, выбранный внешним запросом, удовлетворяет условиям задачи и должен попасть в результирующую выборку.

Пример: Получить названия регионов, в которых нет ни одного отдела:

SELECT name

FROM s_region

WHERE NOT EXISTS (SELECT id

FROM s_dept

WHERE region_id=s_region.id);

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

Результат:

no rows selected –Таких регионов нет

Многостолбцовые подзапросы используются, когда требуется провести сравнение двух или более столбцов. В этом случае перед оператором сравнения в предложении WHERE указывается список сравниваемых столбцов (или выражений) через запятую в скобках. Такое же количество столбцов (или выражений) должен возвращать подзапрос. При этом, чтобы строка внешнего запроса попала в выборку, необходимо, чтобы строка, возвращаемая подзапросом полностью совпадала со строкой перед оператором сравнения в предложении WHERE.

Пример: Получить номера служащих, у которых должность и год приема на работу совпадают как с должностью, так и с годом приема на работу какого-либо служащего отдела №34:

SELECT id

FROM s_emp

WHERE (title, TO_CHAR(start_date,'yyyy')) IN

(SELECT title, TO_CHAR(start_date,'yyyy')

FROM s_emp

WHERE dept_id=34)

AND dept_id<>34;

-- Сами служащие отдела №34 исключаются из запроса (dept_id<>34), так как -- очевидно, что они удовлетворяют условиям запроса.

Результат:

ID

-----

Если требуется сравнение нескольких столбцов, но нет необходимости, чтобы равенство выполнялось для всей строки в целом, необходимо использовать предложение WHERE с несколькими условиями.

Пример: Получить номера служащих, у которых должность совпадает с должностью какого-либо служащего отдела №34 и год приема на работу совпадает с годом приема на работу какого-либо служащего отдела №34. В отличие от предыдущего примера это может быть не один и тот же служащий:

SELECT id

FROM s_emp

WHERE title IN (SELECT title

FROM s_emp

WHERE dept_id=34)

AND TO_CHAR(start_date,'yyyy') IN (SELECT TO_CHAR(start_date,'yyyy')

FROM s_emp

WHERE dept_id=34)

AND dept_id<>34;

-- Сами служащие отдела №34 исключаются из запроса (dept_id<>34), так как -- очевидно, что они удовлетворяют условиям запроса.

Результат:

ID

-----