3. Выражения

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

Таблица 3.1 Описание элементов в выражениях

Элемент

Описание

Имя столбца

Идентификаторы столбцов из указанных таблиц, используемые в вычислениях, или сравнениях, или в качестве условия поиска. Столбец типа массив не может быть элементом выражения, если только он не проверяется на IS [NOT] NULL

Элементы массива

В выражении может содержаться ссылка на элемент массива, т.е. <имя массива>[<индекс>]

Арифметические операторы

Символы +, -, *, / используемые для вычисления значений

Оператор конкатенации

Оператор || используется для соединения символьных строк.

Логические операторы

Зарезервированные слова NOT, AND и OR используются при комбинировании простых условий поиска для создания сложных утверждений

Операторы сравнения

Символы =, <>, !=, ~=, ^=, <, <=, >, >=, !<, ~<, ^<, !>, ~> и ^>

Предикаты сравнения

LIKE, STARTING WITH, CONTAINING, SIMILAR TO, BETWEEN, IS [NOT] NULL и IS [NOT] DISTINCT FROM

Предикаты существования

Предикаты, используемые для проверки существования значений в наборе. Предикат IN может быть использован как с наборами констант, так и со скалярными подзапросами. Предикаты EXISTS, SINGULAR, ALL ANY, SOME могут быть использованы только с подзапросами.

Константы

Числа, заключённые в апострофы строковые литералы, логические значения TRUE, FALSE и UNKNOWN, псевдозначение NULL

Литералы дат

Выражения, подобные строковым литералам, заключённые в апострофах, которые могут быть интерпретированы как значения даты, времени или даты-времени. Литералами дат могут быть предварительно объявленные литералы ('TODAY', 'NOW' и т.д.) или строки из символов и чисел, такие как '25.12.2016 15:30:35', которые могут быть преобразованы в дату, время или дату с временем

Контекстные переменные

Встроенные контекстные переменные

Подзапросы

Оператор SELECT заключённый в круглые скобки, который возвращает одно единственное (скалярное) значение или множество значений (при использовании в предикатах существования)

Локальные переменные

Локальные переменные, входные или выходные параметры PSQL модулей (хранимых процедур, триггеров, анонимных блоков PSQL).

Позиционные параметры

В DSQL в качестве параметров запроса могут быть использованы только позиционные параметры. Позиционные параметры представляют собой знаки вопроса (?) внутри DSQL оператора. Доступ к таким параметрам осуществляется по его номеру (позиции в запросе относительно предыдущего позиционного параметра) поэтому они называются позиционными. Обычно компоненты доступа позволяют работать с именованными параметрами, которые они сами преобразовывают в позиционные

Идентификаторы функций

Идентификаторы встроенных или внешних функций в функциональных выражениях

Приведения типа

Выражение явного преобразования одного типа данных в другой (CAST) или сокращённое (для даты/времени) преобразование типа

Условные выражения

Выражение CASE и встроенные функции COALESCE, NULLIF

Круглые скобки

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

Предложение COLLATE

Предложение применяется к типам CHAR и VARCHAR, чтобы в указанной кодировке установить параметры сортировки, используемые при сравнении

NEXT VALUE FOR

Конструкция NEXT VALUE FOR позволяет получить следующее значение последовательности, то же самое делает встроенная функция GEN_ID()

Выражение AT

Выражение для изменения часового пояса даты и времени.

3.1. Подзапросы

Подзапрос — это специальный вид выражения, которое фактически является запросом SELECT к другой таблице, включённый в спецификацию основного запроса. Подзапросы пишутся как обычные SELECT запросы, но должны быть заключены в круглые скобки. Выражения подзапроса используется следующими способами:

  • Для задания выходного столбца в списке выбора SELECT;

  • Для получения значений или условий для предикатов поиска (предложения WHERE, HAVING).

Коррелированные подзапросы

Подзапрос может быть коррелированным (соотнесённым). Запрос называется соотнесённым, когда оба, и внутренний, и внешний, запросы взаимозависимы. Это означает, что для обработки каждой записи внутреннего запроса, должна быть получена также запись внешнего запроса, т.е. внутренний запрос всецело зависит от внешнего.

SELECT CUST_NO, CONTACT_FIRST,CONTACT_LAST,PHONE_NO
FROM CUSTOMER C
WHERE EXISTS
          (SELECT *
           FROM SALES S
           WHERE C.CUST_NO = S.CUST_NO AND S.ORDER_DATE = DATE '07.02.1994' );

Подзапросы возвращающие скалярный результат

Подзапросы, используемые в предикатах поиска, кроме предикатов существования и количественных предикатов, должны возвращать скалярный результат, то есть не более чем один столбец из одной отобранной строки или одно агрегированное значение, в противном случае, произойдёт ошибка времени выполнения ("Multiple rows in a singleton select...").

SELECT
     e.first_name,
     e.last_name,
     e.salary
FROM employee e
WHERE
     e.salary = (SELECT MAX(ie.salary)
                 FROM employee ie);

3.2. Предикаты

Предикат — это простое выражение, утверждающее некоторый факт. Предикат может быть истинным (TRUE), ложным (FALSE) и неопределённым (UNKNOWN). В SQL ложный и неопределённый результаты трактуются как ложь.

В SQL предикаты проверяют в ограничении CHECK, предложении WHERE, выражении CASE, условии соединения во фразе ON для предложений JOIN, а также в предложении HAVING. В PSQL операторы управления потоком выполнения проверяют предикаты в предложениях IF, WHILE и WHEN.

Проверяемые условия не всегда являются простыми предикатами. Они могут быть группой предикатов, каждый из которых при вычислении делает вклад в вычислении общей истинности. Такие сложные условия называются утверждениями. Утверждения могут состоять из одного или нескольких предикатов, связанных логическими операторами AND, OR и NOT.

Каждый из предикатов может содержать вложенные предикаты. Результат вычисления истинности утверждения получается в результате вычисления всех предикатов по направлению от внутренних к внешним. Каждый «уровень» вычисляется в порядке приоритета, до тех пор, пока невозможно будет получить окончательное утверждение.

Предикаты сравнения

Предикат сравнения представляет собой два выражения, соединяемых оператором сравнения. К операторам сравнения относятся традиционные операторы (< , > , =, ...), а также другие перечисленные далее операторы.

Оператор BETWEEN

Оператор BETWEEN проверяет, попадает (или не попадает при использовании NOT) ли значение во включающий диапазон значений (включая границы).

Листинг 3.1 Синтаксис оператора BETWEEN

<значение> [NOT] BETWEEN <значение 1> AND <значение 2>

Условие будет истинным, если значение присутствует в указанном диапазоне (от <значение 1> включительно до <значение 2> включительно) при отсутствии ключевого слова NOT. При наличии ключевого слова NOT условие будет истинным, если значение отсутствует в указанном диапазоне, включая граничные значения.

Оператор BETWEEN является включающим, то есть значения, совпадающие с границами диапазона, дают значение "истина". Чтобы исключить граничные значения из условия, нужно создать несколько более сложную конструкцию, например:

(<значение> BETWEEN <значение 1> AND <значение 2>) AND
(<значение> NOT IN (<значение 1>, <значение 2>))

Оператор BETWEEN использует два аргумента совместимых типов. В отличие от некоторых других СУБД в РЕД Базе Данных оператор BETWEEN не является симметричным. Меньшее значение должно быть первым аргументом, иначе предикат BETWEEN всегда будет ложным.

Пример

Если в таблице сотрудников STAFF нужно выбрать только тех сотрудников, которые имеют оклады (столбец SALARY) в соответствующем диапазоне, включая граничные значения, то следует выполнить следующий оператор:

SELECT EMP_NO, FIRST_NAME, LAST_NAME,PHONE_EXT
FROM EMPLOYEE
WHERE SALARY BETWEEN 100000 AND 200000;

Оператор LIKE

Предикат LIKE сравнивает выражение символьного типа с шаблоном.

Листинг 3.2 Синтаксис оператора LIKE

<значение> [NOT] LIKE <шаблон> [ESCAPE <символ экранирования>]

Этот вариант является чувствительным к регистру (за исключением случаев, когда само поле определено с сортировкой (COLLATION) нечувствительной к регистру).

В шаблоне можно указать трафаретные символы % и _. Символ процента задает произвольное количество, в том числе и нулевое, любых символов. Знак подчеркивания задает ровно один любой символ.

SELECT DEPT_NO FROM DEPARTMENT WHERE DEPARTMENT LIKE 'Software%';

Необязательное ключевое слово ESCAPE позволяет в шаблон включить и сами трафаретные символы % и _. После ESCAPE нужно указать символ, который должен предшествовать в шаблоне трафаретному символу, когда такой трафаретный символ должен рассматриваться как обычный символ, присутствующий в строке.

SELECT
RDB$RELATION_NAME
FROM RDB$RELATIONS
WHERE RDB$RELATION_NAME LIKE '%#_%' ESCAPE '#';

Для того чтобы в строке также можно было использовать обычным образом и символ, заданный после ключевого слова ESCAPE, необходимо задать его в этой строке дважды.

Примечание

В общем случае предикат LIKE не использует индекс. Однако если предикат принимает вид LIKE 'строка%', то он будет преобразован в предикат STARTING WITH, который будет использовать индекс. Если вам необходимо выполнить поиск с начала строки, то вместо предиката LIKE рекомендуется использовать предикат STARTING WITH.

Оператор STARTING WITH

Оператор STARTING WITH ищет строку или тип, подобный строке, которая начинается с символов в его аргументе.

Листинг 3.3 Синтаксис оператора STARTING WITH

<значение> [NOT] STARTING [WITH] <значение 1>

Оператор чувствителен к регистру, однако такое ограничение также можно легко обойти, используя функцию UPPER или функцию LOWER.

При использовании предиката STARTING WITH в поисковых условиях DML запросов, оптимизатор может использовать индекс по искомому столбцу, если он определён.

SELECT LAST_NAME, FIRST_NAME
FROM EMPLOYEE
WHERE LAST_NAME STARTING WITH 'Jo';

Оператор CONTAINING

Оператор CONTAINING ищет строку или тип, подобный строке, отыскивая последовательность символов, которая соответствует его аргументу.

Листинг 3.4 Синтаксис оператора CONTAINING

<значение> [NOT] CONTAINING <значение 1>

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

Поиск CONTAINING не чувствителен к регистру. Тем не менее, если используется сортировка чувствительная к акцентам, то поиск будет чувствителен к акцентам.

При использовании оператора CONTAINING во внимание принимаются все символы строки. Это касается так же начальных и конечных пробелов. Если операция сравнения в запросе должна вернуть все строки, содержащие строки CONTAINING 'абв ' (с символом пробела на конце), то строка, содержащая 'абв' (без пробела), не будет возвращена.

При использовании предиката CONTAINING в поисковых условиях DML запросов, оптимизатор не может использовать индекс по искомому столбцу.

SELECT PROJ_NAME
FROM PROJECT
WHERE PROJ_NAME CONTAINING 'map';

PROJ_NAME
====================
AutoMap
MapBrowser port

Оператор SIMILAR TO

Оператор SIMILAR TO проверяет соответствие строки шаблону регулярного выражения SQL. Для успешного выполнения шаблон должен соответствовать всей строке — соответствие подстроки не достаточно. Если один из операндов имеет значение NULL, то и результат будет NULL. В противном случае результат является TRUE или FALSE. Предикат может быть использован в любом контексте, который принимает булевы (логические) выражения, такие как предложения WHERE, ограничения CHECK и PSQL-оператор IF().

Синтаксис оператора SIMILAR TO:

Листинг 3.5 Синтаксис оператора SIMILAR TO

<строка> [ NOT ] SIMILAR TO <регулярное выражение> [ESCAPE <символ
экранирования>]

<регулярное выражение> := <строковый элемент> [<квантификатор>] [['|'] <строковый элемент> [ <квантификатор>] ...]

<квантификатор> ::= ? | * | + | '{' m [,[n]] '}'

<строковый элемент> ::= { <экранированный символ> | <обычный символ>}
                        | %
                        | <класс символов>
                        | ( <регулярное выражение> )

<экранированный символ> ::= <символ экранирования> <специальный символ>
                          | <символ экранирования> <символ экранирования>

<специальный символ> ::= '[' | ']' | '(' | ')' | '|' | '^' | '-' | '+' | '*' | '%' | '_' | '?' | '{' | '}'

<обычный символ> ::= любой символ за исключением <специальный символ> и не эквивалентный <символ экранирования> (если задан)

<класс символов> ::= '_'
                   | '[' <элемент класса> ... ']'
                   | '[^' <не элемент класса> ... ']'
                   | '[' <элемент класса> ... '^' <не элемент класса> ... ']'

<элемент класса>, <не элемент класса> ::= {<экранированный символ>|<обычный символ>}
                                         | <диапазон>
                                         | <предопределенные классы>

<диапазон> ::= { <экранированный символ> | <обычный символ>} -
               { <экранированный символ> | <обычный символ>}

<предопределенные классы> ::= '[:'ALPHA':]' | '[:'UPPER':]' | '[:'LOWER':]'
                            | '[:'DIGIT':]' | '[:'ALNUM':]' | '[:'SPACE':]'
                            | '[:'WHITESPACE':]'
Символы

Регулярные выражения в основном состоят из символов, представляющих сами себя. Но есть исключения - это специальные символы:

[] ( ) | ^ - + * % _ ? { }

и управляющие символы.

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

'Symbol' SIMILAR TO 'Symbol',     -- <true>
'Symbols' SIMILAR TO 'Symbol',    -- <false>
'SYMBOL' SIMILAR TO 'Symbol'      -- в зависимости от сортировки
Шаблоны

SQL шаблонам _ и % соответствует любой единственный символ и строка любой длины (в том числе и пустая), соответственно:

'Template' SIMILAR TO 'Te_plate',    -- <true>
'Template' SIMILAR TO 'T_plate',     -- <false>
'Template' SIMILAR TO 'T%te'         -- <true>
Классы символов

Символы, заключенные в квадратные скобки, определяют класс символов. Если символ в строке соответствует классу, то символ является элементом класса. Причем классу соответствует единственный символ строки.

Два символа, соединенные дефисом, в определении класса определяют диапазон. Диапазон для сопоставления включает в себя эти два конечных символа и все символы, находящиеся между ними.

'Class' SIMILAR TO 'Cla[o-y]s',      -- <true>
'Class' SIMILAR TO 'C[la]ss',        -- <false>
'Class' SIMILAR TO 'C[abd-sx]ass'    -- <true>

Если определение класса запускается со знаком вставки (^), то все, что следует за ним, исключается из класса. Все остальные символы проверяются. Если знак вставки (^) находится не в начале последовательности, то класс включает в себя все символы до него и исключает символы после него.

'Error' SIMILAR TO 'Er[^a-g]or',        -- <true>
'Error' SIMILAR TO 'Err[^e-p][^a-g]',   -- <false>
'Error' SIMILAR TO 'Er[wrt^a-d]or'      -- <true>

В определении класса также могут использоваться предопределенные классы символов из таблицы 3.2.

Таблица 3.2 Идентификаторы класса символов

Идентификатор

Описание

ALPHA

Все латинские буквы (a-z, A-Z)

UPPER

Все прописные латинские буквы (A-Z)

LOWER

Все строчные латинские буквы (a-z)

DIGIT

Все арабские цифры (0-9)

SPACE

Пробел (ASCII 32)

WHITESPACE

Все символы-разделители (горизонтальная табуляция, перевод строки, вертикальная табуляция, возврат каретки, перевод страницы, пробел)

ALNUM

Все латинские буквы (ALPHA) и арабские цифры (DIGIT)

Включение в оператор SIMILAR TO предопределенного класса имеет тот же эффект, как и включение всех его элементов. Использование предопределенных классов допускается только в пределах определения класса. Если определение класса запускается со знаком вставки (^), то всё, что следует за ним, исключается из класса. Все остальные символы проверяются. Если знак вставки (^) находится не в начале последовательности, то класс включает в себя все символы до него и исключает символы после него.

'Identifier' SIMILAR TO 'Id[[:ALNUM:]]nti[a-m]ier',     -- <true>
'Identifier' SIMILAR TO 'Ide[[:ALPHA:]^f-o]tifier',     -- <false>
'Identifier' SIMILAR TO 'Ident[^[:DIGIT:]]fier'         -- <true>
Кванторы

Квантор после символа, символьного класса или группы определяет, сколько раз предшествующее выражение может встречаться.

Вопросительный знак (?) сразу после символа, класса или группы указывает на то, что для соответствия предыдущий элемент может произойти 0 или 1 раз.

Звёздочка (*) сразу после символа, класса или группы указывает на то, что для соответствия предыдущий элемент может произойти 0 или более раз.

Знак плюс (+) сразу после символа, класса или группы указывает на то, что для соответствия предыдущий элемент может произойти 1 или более раз.

'Question' SIMILAR TO 'Questt?ion',       -- <true>
'Asterisk' SIMILAR TO 'Ast[c-s]*sk',      -- <true>
'Plus' SIMILAR TO 'Plus[[:DIGIT:]]+'      -- <false>

Если символ или класс сопровождаются числом, заключённым в фигурные скобки ({n}), то для соответствия нужно повторение элемента точно это число раз. Если число сопровождается запятой ({n,}), то для соответствия нужно повторение элемента как минимум это число раз. Если фигурные скобки содержат два числа ({m,n}) и второе число больше первого, то для соответствия элемент должен быть повторен как минимум m раз и не больше n раз.

'Braces' SIMILAR TO 'Bra{2}ces',        -- <false>
'Braces' SIMILAR TO 'Bra[aceg]{2,}s',   -- <true>
'Braces' SIMILAR TO 'Br[aceg]{1,2}s'    -- <false>
Условие ИЛИ

В условиях регулярных выражений можно использовать оператор ИЛИ (|). Соответствие произошло, если строка параметра соответствует по крайней мере одному из условий:

'Condition' SIMILAR TO 'Condi|tion',                -- <false>
'Condition' SIMILAR TO 'Condition|Statement',       -- <true>
'Condition' SIMILAR TO 'Condi_+|Kondi_+|Ckondi_+'   -- <true>
Группы

Одна или более частей регулярного выражения могут быть сгруппированы в подвыражения. Для этого их нужно заключить в круглые скобки:

'Groups' SIMILAR TO 'G(ru|ro|ra)ups'     -- <true>
Экранирование специальных символов

Для исключения из процесса сопоставления специальных символов (которые часто встречаются в регулярных выражениях) их надо экранировать. Специальных символов экранирования по умолчанию нет — их при необходимости определяет пользователь:

'Russia(RU)' SIMILAR TO 'R[a-z]+\(R[A-Z]+\)' ESCAPE '\',      -- <true>
'France[FR]' SIMILAR TO 'Fr[a-z]+#[F%#]' ESCAPE '#',     -- <true>
'Puerto-Rico' SIMILAR TO 'P%$-R%' ESCAPE '$'              -- <true>

Оператор IS DISTINCT FROM

Это оператор проверки на неравенство (равенство, если задано NOT) двух значений.

Листинг 3.6 Синтаксис оператора IS DISTINCT FROM

<значение 1> IS [NOT] DISTINCT FROM <значение 2>

Два операнда считают различными (DISTINCT), если они имеют различные значения, или если одно из них — NULL, и другое нет. Они считаются равными (NOT DISTINCT), если имеют одинаковые значения или оба имеют значение NULL.

SELECT FISCAL_YEAR, PROJ_ID, PROJECTED_BUDGET 
FROM PROJ_DEPT_BUDGET
WHERE FISCAL_YEAR IS DISTINCT FROM '1994';

В отличие от операторов равно (=) и не равно (!=, <>) этот оператор трактует два сравниваемых пустых значения NULL как равные друг другу. Как и в случае оператора IS [NOT] NULL данный оператор всегда возвращает либо TRUE, либо FALSE.

Таблица 3.3 Результаты выполнения различных операторов сравнения

=

IS NOT DISTINCT FROM

!=, <>

IS DISTINCT FROM

Одинаковые значения

TRUE

TRUE

FALSE

FALSE

Различные значения

FALSE

FALSE

TRUE

TRUE

Оба NULL

UNKNOWN

TRUE

UNKNOWN

FALSE

Одно NULL

UNKNOWN

FALSE

UNKNOWN

TRUE

Оператор IS

Оператор IS проверяет, что выражение в левой части является псевдо значением NULL или соответствует логическому значению в правой части.

Листинг 3.7 Синтаксис оператора IS

<значение> IS [NOT] {TRUE | FALSE | UNKNOWN | NULL}

Если в правой части предиката использованы литерал TRUE, FALSE или UNKNOWN, то выражение в левой части должно быть логического типа, иначе будет выдана ошибка.

Оператор может вернуть только истинное значение TRUE или ложное FALSE, значение UNKNOWN невозможно.

Предикаты существования

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

Предикат EXISTS

Если результат подзапроса будет содержать хотя бы одну запись, то предикат EXISTS оценивается как истинный (TRUE), в противном случае предикат оценивается как ложный (FALSE).

Листинг 3.8 Синтаксис предиката EXISTS

[NOT] EXISTS (<оператор SELECT>)

Аргументом предиката EXISTS является оператор SELECT, возвращающий произвольное количество любых столбцов таблицы.

SELECT *
FROM employee
WHERE NOT EXISTS (SELECT *
                  FROM employee_project ep
                  WHERE ep.emp_no = employee.emp_no);

Предикат IN

Предикат IN проверяет, присутствует ли значение выражение в указанном справа наборе значений.

Листинг 3.9 Синтаксис предиката IN

<значение> [NOT] IN (<оператор SELECT> | <список значений>)

<список значений> ::= <значение_1> [, <значение_2> ...]

Набор значений не может превышать 1500 элементов. Предикат IN может быть переписан в следующей эквивалентной форме:

(<значение> = <значение_1> [OR <значение> = <значение_2> ...])
SELECT *
FROM EMPLOYEE
WHERE FIRST_NAME IN ('Pete', 'Ann', 'Roger');

Во второй форме предикат IN проверяет, присутствует (или отсутствует, при использовании NOT IN) ли значение выражения слева в результате выполнения подзапроса справа. Результат подзапроса может содержать только один столбец, иначе будет выдана ошибка "count of column list and variable list do not match".

Запросы с использованием предиката IN с подзапросом, можно переписать на аналогичный запрос с использованием предиката EXISTS.

Например, следующий запрос:

SELECT model, speed, hd
FROM PC
WHERE model IN (SELECT model
                FROM product
                WHERE maker = 'A');

можно переписать на аналогичный запрос с использованием предиката EXISTS:

SELECT model, speed, hd
FROM PC
WHERE EXISTS (SELECT *
              FROM product
              WHERE maker = 'A' AND product.model = PC.model);

Однако, запрос с использованием NOT IN не всегда даст тот же результат, что запрос NOT EXISTS. Причина заключается в том, что предикат EXISTS всегда возвращает TRUE или FALSE, тогда как предикат IN может вернуть NULL в следующих случаях:

  1. Когда проверяемое значение равно NULL и список в IN не пуст.

  2. Когда проверяемое значение не имеет совпадений в списке IN и одно из значений является NULL.

В этих двух случаях предикат IN вернёт NULL, в то время как соответствующий предикат EXISTS вернёт FALSE. В поисковых условиях или операторе IF оба результата обозначают «провал» и обрабатываются одинаково.

Однако на тех же данных NOT IN вернёт NULL, в то время как NOT EXISTS вернёт TRUE, что приведёт к противоположному результату.

Символьные данные в предикате чувствительны к регистру.

Этот предикат может применяться к любому типу данных, кроме типа данных BLOB.

В предикате неявно допускается и пустое значение NULL.

При использовании предиката IN в поисковых условиях DML запросов, оптимизатор может использовать индекс по искомому столбцу, если он определён.

Предикат SINGULAR

Предикат SINGULAR использует подзапрос в качестве аргумента и оценивает его как истинный, если подзапрос возвращает одну и только одну строку результата, в противном случае предикат оценивается как ложный.

Листинг 3.10 Синтаксис предиката SINGULAR

[NOT] SINGULAR (<оператор SELECT>)

Аргументов предиката SINGULAR является оператор SELECT, возвращающий произвольное количество любых столбцов таблицы (обычно это *). Данный предикат может принимать только два значения: истина (TRUE) и ложь (FALSE)

Количественные предикаты подзапросов

Квантором называется логический оператор, задающий количество объектов, для которых данное утверждение истинно. Это логическое количество, а не числовое; оно связывает утверждение с полным множеством возможных объектов. Такие предикаты основаны на формальных логических квантификаторах общности и существования, которые в формальной логике записываются как \(\forall\) и \(\exists\).

Оператор ALL

При использовании квантора ALL, предикат является истинным, если каждое значение выбранное подзапросом удовлетворяет условию в предикате внешнего запроса.

Листинг 3.11 Синтаксис квантора ALL

<значение> <оператор сравнения> ALL (<оператор SELECT>)

Здесь используется операторы сравнения, описанные выше в этом разделе, а также оператор IS [NOT] DISTINCT FROM.

Если подзапрос не возвращает ни одной строки, то предикат автоматически считается верным.

SELECT EMP_NO
FROM EMPLOYEE
WHERE salary > ALL (SELECT salary
                    FROM EMPLOYEE
                    WHERE JOB_COUNTRY = 'France');

Операторы SOME и ANY

Синтаксис использования этих кванторов:

Листинг 3.12 Синтаксис кванторов SOME и ANY

<значение> <оператор сравнения> { SOME | ANY } (<оператор SELECT>)

Ключевые слова SOME и ANY являются синонимами. Результатом будет "истина", если сравнение истинно хотя бы для одного значения, полученного из оператора SELECT.

Если подзапрос не возвращает ни одной строки, то предикат автоматически считается ложным.