Скачиваний:
65
Добавлен:
01.04.2014
Размер:
627.71 Кб
Скачать

8.3.15. Получить имена поставщиков, которые не поставляют деталь р2

См. аналогичные примеры в главах 6 и 7.

SELECT DISTINCT S.SNAME

FROM S

WHERE NOT EXISTS

( SELECT *

FROM SP

WHERE SP.S# = S.S#

AND SP.P# = 'Р2' ) ;

Или альтернативная формулировка:

SELECT DISTINCT S.SNAME FROM S

WHERE S.S# NOT IN

( SELECT SP.S#

FROM SP

WHERE SP.P# = 'P2' ) ;

8.3.16. Получить имена поставщиков, поставляющих все детали

См. аналогичные примеры в главах 6 и 7.

SELECT DISTINCT S.SNAME

FROM S

WHERE NOT EXISTS

( SELECT *

FROM P

WHERE NOT EXISTS

( SELECT *

FROM SP

WHERE SP.S# = S.S#

AND SP.P# = P.P# ) ) ;

Язык SQL не включает какой-либо непосредственной поддержки универсального квантора forall; следовательно, запросы типа forall обычно выражаются через отри­цание кванторов существования, как в этом примере.

Стоит отметить, что такие выражения, как только что показанное, хотя на первый взгляд и выглядят несколько устрашающе, легко составляются пользователями, зна­комыми с реляционным исчислением, как отмечалось в [7.6]. Или с другой стороны, если эти примеры еще кажутся слишком сложными, то существует несколько "обходных" приемов, которые помогут избежать использования негативных кванто­ров. В нашем случае можно, например, записать:

SELECT DISTINCT S.SNAME

FROM S

WHERE ( SELECT COUNT ( SP.P# )

FROM SP

WHERE SP.S# = S.S# ) = ( SELECT COUNT ( P.P# )

FROM P);

("имена поставщиков, для которых количество поставляемых деталей равно количе­ству всех деталей"). Однако обратите внимание на следующие обстоятельства.

• Во-первых, в последней формулировке предполагается, в отличие от формулировки с выражением not exists, что нет номеров деталей в отношении SP, которые не содер­жатся в отношении Р. Другими словами, эти две формулировки эквивалентны (а вто­рая — верная) только благодаря действию определенного ограничения целостности.

• Во-вторых, метод, примененный во второй формулировке (сравнение двух коли­честв), изначально не поддерживался в SQL и был добавлен в стандарт SQL/92. Он все еще не поддерживается во многих продуктах.

• Отметим также, что на самом деле предпочтительнее было бы сравнивать две таблицы (см. обсуждение реляционных сравнений в главе 6), и тогда запрос записывался бы так:

SELECT DISTINCT S.SNAME

FROM S

WHERE ( SELECT SP.P# )

FROM SP

WHERE SP.S# = S.S# ) = ( SELECT P.P#

FROM P);

Поскольку язык SQL непосредственно не поддерживает сравнения между таблицами, необходимо прибегнуть к приему, использующему сравнение карди­нальных чисел (количество строк) таблиц (опираясь на практический опыт, мы убе­ждаемся, что если кардинальные числа таблиц одинаковы, то и таблицы одинаковы, по крайней мере, в обсуждаемом случае).

Соседние файлы в папке Дейтл Введ в БД