при цьому користувач указує складні критерії відбору рядків, то в розділі WHERE змішуються семантично різні поняття - як умови зв'язку таблиць, так і умови відбору рядків (див. приклади 13, 14, 15 даного розділу).
Синтаксис умовних виразів розділу WHERE
Умовний вираз, що використовується в розділі WHERE оператора SELECT повинне обчислюватися для кожного рядка-кандидата, відбираного оператором SELECT. Умовний вираз може повертати одне з трьох значень істинності: TRUE, FALSE або UNKNOUN. Рядок-кандидат відбирається в результуючу множину рядків тільки в тому випадку, якщо для неї умовний вираз повернув значення TRUE.
Умовні вирази мають наступний синтаксис (в цілях спрощення викладу приведені не всі можливі предикати):
Умовний вираз ::=
[ ( ] [NOT]
{Предикат порівняння
| Предикат between
| Предикат in
| Предикат like
| Предикат null
| Предикат кількісного порівняння
| Предикат exist
| Предикат unique
| Предикат match
| Предикат overlaps}
[| OR}
[IS [NOT] {TRUE | FALSE | UNKNOWN}]
Предикат порівняння ::=
Конструктор значень рядка {= | < | > | <= | >= | <>} Конструктор значень рядка
Приклад 33. Порівняння поля таблиці і скалярного значення:
POSTAV.VOLUME > 100
Приклад 34. Порівняння двох сконструйованих рядків:
(PD.PNUM, PD.DNUM) = (1, 25)
Цей приклад еквівалентний умовному виразу
PD.PNUM = 1 AND PD.DNUM = 25
Предикат between ::=
Конструктор значень рядка [NOT] BETWEEN
Конструктор значень рядка AND Конструктор значень рядка
Приклад 35. PD.VOLUME BETWEEN 10 AND 100
Предикат in ::=
Конструктор значень рядка [NOT] IN{(Select-вираз) | (Вираз для обчислення значення...)}
Приклад 36.
P.PNUM IN (SELECT PD.PNUM FROM PD WHERE PD.DNUM=2)
Приклад 37.
P.PNUM IN (1, 2, 3, 5)
Предикат like ::=
Вираз для обчислення значення рядка-пошуку [NOT] LIKEВираз для обчислення значення рядка-шаблона [ESCAPE Символ]
Зауваження. Предикат LIKE проводить пошук рядка-пошуку в рядку-шаблоні. В рядку-шаблоні дозволяється використовувати два трафаретні символи:
Символ підкреслення "_" може використовуватися замість будь-якого одиничного символу в рядку пошуку
Символ відсотка "%" може замінювати набір будь-яких символів в рядку пошуку (число символів в наборі може бути від 0 і більш).
Предикат null ::=
Конструктор значень рядка IS [NOT] NULL
Зауваження. Предикат NULL застосовується спеціально для перевірки, чи не рівний вираз null-значенню, що перевіряється.
Предикат кількісного порівняння ::=
Конструктор значень рядка {= | < | > | <= | >= | <>}
{ANY | SOME | ALL} (Select-вираз)
Зауваження. Квантори ANY і SOME є синонімами і повністю взаємозамінні.
Зауваження. Якщо вказаний один з кванторів ANY і SOME, то предикат кількісного порівняння повертає TRUE, якщо порівнюване значення співпадає хоча б з одним значенням, що повертається в підзапиті (select-виразі).
Зауваження. Якщо вказаний квантор ALL, то предикат кількісного порівняння повертає TRUE, якщо порівнюване значення співпадає з кожним значенням, що повертається в підзапиті (select-виразі).
Приклад 38.
P.PNUM = SOME (SELECT PD.PNUM FROM PD WHERE PD.DNUM=2)
Предикат exist ::=
EXIST (Select-вираз)
Зауваження. Предикат EXIST повертає значення TRUE, якщо результат підзапиту (select-вирази) не порожній.
Предикат unique ::=
UNIQUE (Select-вираз)
Зауваження. Предикат UNIQUE повертає TRUE, якщо в результаті підзапиту (select-вирази) немає співпадаючих рядків.
Предикат match ::=
Конструктор значень рядка MATCH [UNIQUE]
[PARTIAL | FULL] (Select-вираз)
Зауваження. Предикат MATCH перевіряє, чи буде значення, визначене в конструкторі рядка співпадати із значенням будь-якого рядка, одержаного в результаті підзапиту.
Предикат overlaps ::=
Конструктор значень рядка OVERLAPS Конструктор значень рядка
Зауваження. Предикат OVERLAPS, є спеціалізованим предикатом, дозволяючому визначити, чи буде вказаний період часу перекривати інший період часу.
Порядок виконання оператора SELECT
Для того, щоб зрозуміти, як виходить результат виконання оператора SELECT, розглянемо концептуальну схему його виконання. Ця схема є саме концептуальною, оскільки гарантується, що результат буде таким, наче він виконувався крок за кроком відповідно до цієї схеми. Насправді, реально результат виходить більш витонченими алгоритмами, якими "володіє" конкретна СУБД.
Стадія 1. Виконання одиночного оператора SELECT
Якщо в операторі присутні ключові слова UNION, EXCEPT і INTERSECT, то запит розбивається на декілька незалежних запитів, кожний з яких виконується окремо:
Крок 1 (FROM). Обчислюється прямий декартовий добуток всіх таблиць, вказаних в обов'язковому розділі FROM. В результаті кроку 1 одержуємо таблицю А.
Крок 2 (WHERE). Якщо в операторі SELECT присутній розділ WHERE, то сканується таблиця А, одержана при виконанні кроку 1. При цьому для кожного рядка з таблиці А обчислюється умовний вираз, приведений в розділі WHERE. Тільки ті рядки, для яких умовний вираз повертає значення TRUE, включаються в результат. Якщо розділ WHERE опущений, то відразу переходимо до кроку 3. Якщо в умовному виразі беруть участь вкладені підзапити, то вони обчислюються відповідно до даної концептуальної схеми. В результаті кроку 2 одержуємо таблицю B.
Крок 3 (GROUP). Якщо в операторі SELECT присутній розділ GROUP, то рядки таблиці B, одержаної на другому кроці, групуються відповідно до списку угрупування, приведеного в розділі GROUP. Якщо розділ GROUP опущений, то відразу переходимо до кроку 4. В результаті кроку 3 одержуємо таблицю З.
Крок 4 (HAVING). Якщо в операторі SELECT присутній розділ HAVING, то групи, що не задовольняють умовному виразу, приведеному в розділі HAVING, виключаються. Якщо розділ HAVING опущений, то відразу переходимо до кроку 5. В результаті кроку 4 одержуємо таблицю D.
Крок 5 (SELECT). Кожна група, одержана на кроці 4, генерує один рядок результату таким чином. Обчислюються всі скалярні вирази, вказані в розділі SELECT. За правилами використовування розділу GROUP, такі скалярні вирази повинні бути однаковими для всіх рядків усередині кожної групи. Для кожної групи обчислюються значення агрегатних функцій, приведених в розділі SELECT. Якщо розділ GROUP був відсутній, але в розділі SELECT є агрегатні функції, то