Всегда есть несколько способов написать одну и ту же вещь в SQL.Например, это
SELECT * FROM
(SELECT A,B FROM Table_1) T1
... можно переписать так:
SELECT A, B
FROM Table_1
Последнее проще, и я не вижу причин предпочитать первое.Переписав ваш первый запрос соответственно
SELECT A, B
FROM Table_1
WHERE EXISTS (
SELECT 'X'
FROM Table_1
WHERE A = 3
);
Я удалил имя корреляции T1
, потому что оно не имеет смысла.Подзапрос не ссылается на свое «внешнее» табличное выражение, поэтому нет необходимости устранять неоднозначность каждого вида Table_1
.
Я думаю, вы понимаете, что здесь происходит: если одна или несколько строк в Table_1
удовлетворяют условию поиска A = 3
, тогда возвращается вся таблица, в противном случае возвращается пустой набор.Несмотря на то, что это допустимый запрос, он часто не очень полезная конструкция.
Однако для второго запроса требуется хотя бы одно имя корреляции, поскольку подзапрос ссылается на свою внешнюю таблицу:
SELECT A, B
FROM Table_1 T1
WHERE EXISTS (
SELECT 'X'
FROM Table_1 T2
WHERE T1.A IN (3, 4)
);
Опять же, это семантически эквивалентно вашему второму запросу.Обратите внимание, что я добавил в подзапросе Table_1
имя корреляции T2
, но T2
не появляется в предложении WHERE
подзапроса.Поскольку T2
не используется, мы можем полностью удалить подзапрос (отсюда и необходимость в именах корреляции):
SELECT A, B
FROM Table_1
WHERE A IN (3, 4);
Стоит отметить, что возможность подзапроса ссылаться на «внешнюю» таблицуВыражение обычно используется как «коррелированный подзапрос», то есть условие поиска (предложение WHERE
) включает в себя как «внутренние», так и «внешние» таблицы (условие поиска вашего второго запроса включает только «внешнюю» таблицу).
Используя обычную базу данных запчастей и поставщиков , здесь приведен пример коррелированного подзапроса для реализации semi-join для поиска поставщиков (S
), которые поставляют (SP
) хотя быодна часть:
SELECT SNO, SNAME
FROM S
WHERE EXISTS (
SELECT *
FROM SP
WHERE SP.SNO = S.SNO
);
Обратите внимание, что условие поиска подзапроса связывает «внешнюю» таблицу SP
с «внутренней» таблицей S
.Кроме того, проекция SELECT SNO, SNAME
во «внешней» таблице не требует включения имени корреляции S
, поскольку SP
из «внешней» таблицы не входит в область действия для «внутренней» таблицы.