SELECT С1.Продукт
FROM Состав С1
WHERE С1.Продукт NOT IN (SELECT С2.Продукт
FROM Состав С2
WHERE С2.Блюдо <> С1.Блюдо);
Данный запрос возвращает пустую таблицу, так нет таких продуктов в БД.
Действие этого запроса можно пояснить следующим образом: "Поочередно для каждой строки таблицы Состав, скажем С1, выделить значение номера продукта (С1.Продукт) и номер блюда (С1.Блюдо), в котором этот продукт используется. А затем проверить, не встречается ли этот продукт в списке продуктов (С2) необходимых для приготовления других блюд (<>С1.Блюдо). Если не встречается, то выводим его".
Отметим, что в этой формулировке должен быть использован по крайней мере один псевдоним - либо С1, либо С2.
Данный запрос может быть реализован и по-другому.
SELECT Продукт
FROM Состав
GROUP BY Продукт
HAVING COUNT (DISTINCT Блюдо) = 1;
Для проверки правильности выводов данных запросов можно выполнить команду:
Результат
|
|
Продукт
|
|
1
|
5
|
2
|
5
|
3
|
19
|
4
|
4
|
5
|
11
|
6
|
10
|
7
|
11
|
8
|
6
|
9
|
7
|
10
|
8
|
11
|
8
|
12
|
13
|
13
|
5
|
14
|
8
|
15
|
9
|
16
|
17
|
17
|
2
| SELECT Продукт , COUNT (DISTINCT Блюдо)
FROM Состав
GROUP BY Продукт;
И получить результат:
4.4 Использование оператора EXISTS.
Квантор EXISTS (существует) - понятие, заимствованное из формальной логики. В языке SQL предикат с квантором существования представляется выражением
… EXISTS (SELECT * FROM ...).
Такое выражение считается истинным только тогда, когда результат вычисления "SELECT * FROM ..." является непустым множеством (вернул хотя бы одну строку). Рассмотрим примеры.
Пример 33.
Выдать названия Блюд, представленных в меню на данное число.
SELECT Блюдо
Результат
|
|
Блюдо
|
Салат летний
|
Салат мясной
|
Паштет из рыбы
|
Суп харчо
|
Суп молочный
|
Бефстроганов
|
Судак по-польски
|
Суфле яблочное
|
Кофе на молоке
| FROM Блюда
WHERE EXISTS (SELECT * FROM Меню m
WHERE m.Блюдо = Блюда.ID_Блюда
and Дата = '2011-01-02');
Система последовательно выбирает строки таблицы Блюда, выделяет из них значения столбцов Блюдо и ID_Блюда, а затем проверяет, является ли истинным условие существования, т.е. существует ли в таблице Меню(m) хотя бы одна строка со значением Дата = '2011-01-02' и значением m.Блюдо, равным значению Блюда.ID_Блюда. Если условие выполняется, то полученное значение столбца Блюдо включается в результат. Соответственно, запрос
SELECT Блюдо
FROM Блюда
WHERE NOT EXISTS (SELECT *
FROM Меню m
WHERE m.Блюдо = Блюда.ID_Блюда );
выдаст названия блюд, которые ни разу не включались в состав меню. Данные запросы также являются соотнесенными.
Хотя этот рассмотренный пример только показывает иной способ формулировки запроса для задачи, решаемой и другими путями (с помощью оператора IN или соединения), EXISTS представляет собой одну из наиболее важных возможностей SQL. Фактически любой запрос, который выражается через IN, может быть альтернативным образом сформулирован также с помощью EXISTS. Однако обратное высказывание несправедливо.
4.5. Использование операторов ANY и ALL.
Операторы ANY и ALL напоминают EXISTS, который воспринимает подзапросы как аргументы; однако они отличаются от EXISTS тем, что используются совместно с реляционными операторами. В этом отношении, они напоминают оператор IN, когда тот используется с подзапросами; они берут все значения выведенные подзапросом и обрабатывают их как модуль. Однако, в отличие от IN, они могут использоваться только с подзапросами.
Оператор ANY.
Оператор ANY означает, что предикат истинен, если хотя бы для одного значения из подзапроса предикат сравнения истинен.
Пример 34.
Имеется иной способ нахождения названий Блюда представленных в меню на данное число.
Do'stlaringiz bilan baham: |