Предикат EXISTS
Синтаксис:
EXISTS::=
[NOT] EXISTS (<табличный подзапрос>)
Предикат EXISTS принимает значение TRUE, если подзапрос содержит любое количество строк, иначе его значение равно FALSE. Для NOT EXISTS все наоборот. Этот предикат никогда не принимает значение UNKNOWN.
Обычно предикат EXISTS используется в зависимых (коррелирующих) подзапросах. Этот вид подзапроса имеет внешнюю ссылку, связанную со значением в основном запросе. Результат подзапроса может зависеть от этого значения и должен оцениваться отдельно для каждой строки запроса, в котором содержится данный подзапрос. Поэтому предикат EXISTS может иметь разные значения для разных строк основного запроса.
Пример на пересечение
SELECT DISTINCT maker
FROM Product AS lap_product
WHERE type = 'laptop'
AND EXISTS (SELECT maker
FROM Product
WHERE type = 'printer'
AND maker = lap_product.maker
);
[[ column ]] |
---|
[[ value ]] |
В подзапросе выбираются производители принтеров и сравниваются с производителем, значение которого передается из основного запроса. В основном же запросе отбираются производители ноутбуков. Таким образом, для каждого производителя ноутбуков проверяется, возвращает ли подзапрос строки (которые говорят о том, что этот производитель также выпускает принтеры). Поскольку два условия в предложении WHERE должны выполняться одновременно (AND), то в результирующий набор попадут нужные нам строки. DISTINCT используется для того, чтобы каждый производитель присутствовал в выходных данных только один раз. В результате получим
maker |
---|
A |
Пример на разность
SELECT DISTINCT maker
FROM Product AS lap_product
WHERE type = 'laptop'
AND NOT EXISTS (SELECT maker
FROM Product
WHERE type = 'printer'
AND maker = lap_product.maker
);
[[ column ]] |
---|
[[ value ]] |
В этом случае достаточно заменить в предыдущем примере EXISTS на NOT EXISTS. То есть выходные данные составят только те уникальные строки основного запроса, для которых подзапрос не возвращает ни одной строки. В итоге получим:
maker |
---|
B |
C |