Справка по SQL | страница 14
>SELECT Product .type, PC.model, price
>FROM PC INNER JOIN
> Product ON PC.model = Product .model
>UNION
>SELECT Product .type, Laptop.model, price
>FROM Laptop INNER JOIN
> Product ON Laptop.model = Product .model
>ORDER BY price DESC;
type | model | price |
---|---|---|
Laptop | 1750 | 1200.0 |
Laptop | 1752 | 1150.0 |
Laptop | 1298 | 1050.0 |
PC | 1233 | 980.0 |
Laptop | 1321 | 970.0 |
PC | 1233 | 950.0 |
PC | 1121 | 850.0 |
Laptop | 1298 | 700.0 |
PC | 1232 | 600.0 |
PC | 1233 | 600.0 |
PC | 1232 | 400.0 |
PC | 1232 | 350.0 |
PC | 1260 | 350.0 |
Пересечение и разность
В стандарте языка SQL имеются предложения оператора SELECT для выполнения операций пересечения и разности запросов. Этими предложениями являются INTERSECT (пересечение) и EXCEPT (разность), которые работают аналогично предложению UNION. В результирующий набор попадают только те строки, которые присутствуют в обоих запросах (INTERSECT) или только те строки первого запроса, которые отсутствуют во втором (EXCEPT).
Однако многие СУБД не поддерживают эти предложения в операторе SELECT. Это справедливо и для MS SQL Server. Поэтому для выполнения операций пересечения и разности могут быть использованы другие средства. Здесь уместно заметить, что один и тот же результат можно получить с помощью различных формулировок оператора SELECT. В случае пересечения и разности можно воспользоваться предикатом существования EXISTS.
Проверка наличия записей. Предикат 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);
В подзапросе выбираются производители принтеров и сравниваются с производителем, значение которого передается из основного запроса. В основном же запросе отбираются производители ПК-блокнотов. Таким образом, для каждого производителя ПК-блокнотов проверяется, возвращает ли подзапрос строки (т.е. этот производитель также производит принтеры). Поскольку два условия в предложении WHERE должны выполняться одновременно (AND), то в результирующий набор попадут нужные строки. DISTINCT используется для того, чтобы каждый производитель присутствовал в выходных данных только один раз. В результате получим: