1200.0
|
1752
|
1150.0
|
1298
|
1050.0
|
1233
|
980.0
|
1321
|
970.0
|
1233
|
950.0
|
1121
|
850.0
|
1298
|
700.0
|
1232
|
600.0
|
1233
|
600.0
|
1232
|
400.0
|
1232
|
350.0
|
1260
|
350.0
|
Пример. Найти тип продукции, номер модели и цену ПК и ПК-блокнотов:
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 используется для того, чтобы каждый производитель присутствовал в выходных данных только один раз. В результате получим:
Пример на разность. Найти тех производителей ПК-блокнотов, которые не производят принтеров:
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);
В этом случае достаточно заменить в предыдущем примере EXIST на NOT EXIST. Т.е. выходные данные составят только те уникальные строки основного запроса, для которых подзапрос не возвращает ни одной строки. В итоге получим:
Использование ключевых слов SOME | ANY и ALL с предикатами сравнения
Читать дальше