- •Часть 2. Реляционная модель.
- •Глава 4. Реляционные объекты данных: домены и отношения.
- •4.1. Вводный пример
- •4.2. Домены
- •4.3. Отношения
- •4.4. Виды отношений
- •4.5. Отношения и предикаты
- •4.6. Реляционные базы данных
- •4.7. Резюме
- •Глава 8.
- •8.1. Введение
- •8.2. Определение данных
- •8.3. Обработка данных: операции выборки
- •8.3.1. Получить цвета и города для деталей "не из Парижа" с весом, большим десяти
- •8.3.2. Для всех деталей получить номер детали и ее вес в граммах
- •8.3.3. Получить полную информацию обо всех поставщиках
- •8.3.4. Получить информацию обо всех парах поставщиков и деталей, совмещенных в одном городе
- •8.3.5. Получить все пары имен городов, таких что поставщик, находящийся в первом городе, поставляет деталь, хранящуюся во втором городе
- •8.3.6. Получить все пары номеров поставщиков, таких что оба поставщика в каждой паре размещаются в одном и том же городе
- •8.3.7. Получить общее число поставщиков
- •8.3.8. Получить максимальное и минимальное количество для детали р
- •8.3.9. Для каждой поставляемой детали получить номер детали и общее количество поставки
- •8.3.10. Получить номера для всех деталей, поставляемых более чем одним поставщиком
- •8.3.11. Получить имена поставщиков, поставляющих деталь р2
- •8.3.12. Получить имена поставщиков, поставляющих по крайней мере одну красную деталь
- •8.3.13. Получить номера поставщиков, статус которых меньше текущего максимального статуса в таблице s
- •8.3.14. Получить имена поставщиков, поставляющих деталь р2
- •8.3.15. Получить имена поставщиков, которые не поставляют деталь р2
- •8.3.16. Получить имена поставщиков, поставляющих все детали
- •8.3.17. Получить номера деталей, которые или весят более 16 фунтов, или поставляются поставщиком s2, или и то и другое
- •8.4. Обработка данных: операции обновления
- •Table-term
- •I join-table-expression
- •8.6. Условные выражения
- •8.7. Скалярные выражения
- •8.8. Встроенный sql
- •8.8.1. Единичный select. Получить статус и город для поставщика, чей номер поставки задан базовой переменной givens#
- •8.8.2. Insert. Вставить новую деталь в таблицу р (номер детали, ее назв. И вес определены базовыми переменными р#, pname, pwt соответственно, цвет и город неизвестны)
- •8.8.3, Update. Увеличить статус всех поставщиков из Лондона на значение, определенное базовой переменной raise
- •8.8.4. Delete. Удалить все поставки для поставщиков из города,
- •8.9. Резюме
8.6. Условные выражения
Как и табличные выражения, условные выражения встречаются в многочисленных контекстах языка SQL и, в частности, используются в инструкции where с целью включения или исключения строк для последующей обработки. Обсудим некоторые наиболее важные свойства таких выражений. При этом обратите внимание, что наша трактовка, несомненно, не претендует на исчерпывающую; в частности, мы пропускаем все, что касается null-значений. (Условные выражения, возможно, больше остальных элементов языка требуют расширенного рассмотрения, если учитывать наличие null-значений и сложность вопросов, связанных с ними. Кроме того, здесь не рассматриваются определенные форматы условных выражений, предназначенные исключительно для определенных аспектов поддержки null-значений.)
Как и выше, начнем с BNF-грамматики (рис. 8.2). Читатель убедится, что большинство форматов условных выражений или уже были проиллюстрированы в предыдущих разделах, или понятны сами по себе; здесь же просто делается попытка в нескольких словах дать пояснения относительно таких характерных случаев, как условия match и "все-или-какой-нибудь".
conditional-expression
: := conditional-term
I conditional-egression OR conditional-term
conditional-term
: := conditional-factor
I conditional- term AND conditional-factor
conditional-factor
: :=[ NOT ] conditionaI-primary
conditional -primary
: := simple-condition | ( conditional-egression )
simple-condition
: := comparison-condition
| in-condition
| match-condition
| all-or-any-condition
| exists-condition
comparison-condition
: := row-constructor comparison-operator row-constructor
comparison-operator
: := = | < | <= | > | >= | <>
in-condition
: := row-constructor [ NOT ] IN ( table-expression )
I scalar-expression [ NOT ] IN
( scalar-expression-commalist )
match-condition
: := row-constructor MATCH UNIQUE ( table-expression )
all-or-any-condition
: := row-constructor
comparison-operator ALL ( table-expression )
I row-constructor
comparison-operator ANY ( table-expression )
exists-condition
: := EXISTS ( table-expression )
Рис. 8.2.BNF-грамматика для условных выражений SQL
Условие MATCH
Условие match имеет следующий вид:
row-constructor MATCH UNIQUE ( tabIe-expression )
Пусть r1 — это строка, полученная в результате вычисления row-constructor, и пусть Т— таблица, полученная в результате вычисления table-expression. Тогда вычисление условия match будет давать истину тогда и только тогда, когда таблица T будет содержать ровно одну строку, скажем r2, такую, что сравнение
r1=r 2
будет давать истину. Вот один пример:
SELECT SP.*
FROM SP
WHERE NOT ( SP.S# MATCH UNIQUE ( SELECT S.S# FROM S ) ) ;
("Получить поставки, которые не имеют ровно одного соответствующего поставщика в таблице поставщиков"). Такой запрос может быть полезен при проверке целостности базы данных, поскольку если база данных корректна, то не должно быть ни одной такой поставки. Заметьте, что для выполнения такой же проверки могло быть использовано условие in.
Кстати, ключевое слово unique из инструкции match unique можно опустить, но тогда match превращается в синоним слова in (по крайней мере, при отсутствии null-значений).
”Условие "все-или-какой-нибудь"
Условие "все-или-какой-нибудь" имеет такую общую форму:
row-constructor
comparison-operator qualifier ( table-expression )
Здесь оператор сравнения (comparison-operator) берется из обычного набора (=, <> и т.д.), а квантор (qualifier)— это ключевое слово all (все) или any (какой-нибудь, существует хотя бы один). В общем, условие "все-или-какой-нибудь" дает значение истина тогда и только тогда, когда соответствующее сравнение без квантора all (или any) дает значение истина для всех (или соответственно для какой-нибудь) строк (строки) таблицы, представляемой выражением table-expression. (Если эта таблица пустая, то условие с квантором all имеет значение истина, а с квантором any — ложь.) Приведем пример ("Получить названия таких деталей, вес которых больше веса любой голубой детали"):
SELECT DISTINCT PX.PNAME
FROM P AS PX
WHERE PX.WEIGHT > ALL ( SELECT PY.WEIGHT
FROM P AS PY
WHERE PY.COLOR = 'Blue' ) ;
Результат будет выглядеть следующим образом:
Пояснения. Вложенное табличное выражение возвращает множество весов голубых (Blue) деталей, а именно множество {17, 12}. Тогда внешнее выражение select возвращает название только одной детали (а именно детали Р6), вес которой больше каждого значения в этом множестве. В общем случае, конечно, результат может содержать любое количество деталей (включая нуль).