Информационные технологии
Операционные системы
Информационные технологии
Информационные технологии представляют собой широкий класс дисциплин и сфер деятельности, которые относятся к технологиям создания, хранения, управления, ... читать далее »
Статьи по ИТ
02.06.2009 00:00

Язык баз данных SQL/92 часть 2. Информационные технологии.

3. Выражения запросов

Хотя на вид (на примерах) выражения запросов SQL/92 очень напоминают соответствующие конструкции SQL/89, на самом деле они гораздо мощнее. Для того, чтобы можно было лучше понять существо выражений запросов SQL/92, мы начнем с рассмотрения вспомогательных конструкций. Заметим, что синтаксические определения часто носят рекурсивный характер, но это "хорошая" рекурсия, потому что в конечном счете любой запрос опирается на именованные базовые или представляемые таблицы.

Итак, сначала введем некоторые начальные понятия, связанные с запросами. Наверное, наиболее важным из таких понятий в SQL/92 является ссылка на таблицу (tablereference), которая может встречаться во всех конструкциях, адресуемых к таблицам. Ссылка на таблицу определяется следующими синтаксическими правилами:

<table reference> ::= <table name> [ [ AS ] <correlation name> 
    
[ <left paren> <derived column list> <right paren> ] ]
|<derived table> [ AS ] <correlation name>
[ <left paren> <derived column list> <right paren> ]
|<joined table>
<derived table> ::= <table subquery>
<derived column list> ::= <column name list>
<column name list> ::=
<column name> [ { <comma> <column name> }... ]

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

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

<row value constructor> ::= 
    
<row value constructor element>
|<left paren> <row value constructor list> <right paren>
|<row subquery>
<row value constructor list> ::=
<row value constructor element>
[ { <comma> <row value constructor element> }... ]
<row value constructor element> ::=
<value expression>
|<null specification>
|<default specification>
<null specification> ::= NULL
<default specification> ::= DEFAULT

Заметим, что значение элемента по умолчанию можно использовать только в том случае, когда конструктор значения-строки используется в операторе INSERT (тогда этим значением будет значение по умолчанию соответствующего столбца).

Конструктор значения-таблицы производит таблицу на основе заданного набора конструкторов значений-строк:

<table value constructor> ::= 
    
VALUES <table value constructor list>
<table value constructor list> ::=
<row value constructor>
[ { <comma> <row value constructor> }... ]

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

3.1. Табличные выражения

Как и в SQL/89, табличное выражение SQL/92 в качестве результата выдает обычную или сгруппированную таблицу:

<table expression> ::= 
    
<from clause>
[ <where clause> ]
[ <group by clause> ]
[ <having clause> ]

Все отличия от SQL/89 сосредоточены в разделах табличного выражения.

3.1.1. Раздел FROM

Формально синтаксис остался таким же, как и в SQL/89:

<from clause> ::= 
    
FROM <table reference>
[ { <comma> <table reference> }... ]

Но вспомним, что такое ссылка на таблицу в SQL/92 (см. выше). Реально можно весь запрос сосредоточить в разделе FROM.

3.1.2. Раздел WHERE

Снова синтаксис формально не изменился:

<where clause> ::= WHERE <search condition> 
    

Но существенно расширен набор допустимых предикатов (см. следующий раздел).

Разделы GROUPBY и HAVING остались такими же, как в SQL/89, если не считать расширения набора предикатов, которые можно использовать в условии HAVING.

Минимальный осмысленный контекст использования табличных выражений составляет спецификация запроса - один из основных строительных блоков для построения выражения запросов. Синтаксис спецификации запросов следующий:

<query specification> ::= 
    
SELECT [ <set quantifier> ] <select list> <table expression>
<select list> ::=
<asterisk>
|<select sublist> [ { <comma> <select sublist> }... ]
<select sublist> ::=
<derived column>
|<qualifier> <period> <asterisk>
<derived column> ::= <value expression> [ <as clause> ]
<as clause> ::= [ AS ] <column name>

Опять же на вид это очень похоже на соответствующую конструкцию SQL/89, но нужно иметь в виду, что, во-первых, в основе спецификации запроса SQL/92 лежит существенно расширенная конструкция табличного выражения, а во-вторых, в спецификации присутствует необязательный раздел AS, позволяющий присвоить имена таблице, которая генерируется при выполнении запроса. Эта возможность кажется на первый взгляд мелочью, но именно она позволяет использовать порождаемые таблицы в разделе FROM и отказаться от использования номеров столбцов порождаемой таблицы в разделе ORDERBY выражения запросов (см. ниже).

3.2. Соединенные таблицы

Конструкция соединенной таблицы - это альтернативный способ порождения новой таблицы на основе использования ранее определенных таблиц (базовых, представляемых или порожденных). Для этой конструкции аналоги в SQL/89 отсутствуют. Фактически соединенная таблица вносит алгебраический стиль в формулировки запросов на языке SQL. Формально соединенная таблица определяется следующими синтаксическими правилами:

<joined table> ::= 
    
<cross join>
|<qualified join>
|<left paren> <joined table> <right paren>
<cross join> ::=
<table reference> CROSS JOIN <table reference>
<qualified join> ::=
<table reference> [ NATURAL ] [ <join type> ] JOIN
<table reference> [ <join specification> ]
<join specification> ::=
<join condition>
|<named columns join>
<join condition> ::= ON <search condition>
<named columns join> ::=
USING <left paren> <join column list> <right paren>
<join type> ::=
INNER
|<outer join type> [ OUTER ]
|UNION
<outer join type> ::=
LEFT
|RIGHT
|FULL
<join column list> ::= <column name list>

Поскольку раньше мы не встречались с подобными конструкциями, приведем сравнительно подробные объяснения. Предположим, что соединяются таблицы T1 и T2. Пусть CP обозначает их расширенное Декартово произведения: CP = SELECT * FROMT1, T2.

  1. Если специфицировано квалифицированное соединение (qualifiedjoin), то
      (a) если указано NATURAL (естественное соединение), то спецификация соединения (joinspecification) должна отсутствовать;
      (b) если указано UNION (объединение), то должны отсутствовать и спецификация соединения, и NATURAL;
      (c) в противном случае спецификация соединения должна присутствовать.
  2. Если специфицировано квалифицированное соединение, и не указан тип соединения (jointype), то неявно предполагается внутреннее (INNER) соединение.
  3. Если специфицировано квалифицированное соединение с условием соединения (joincondition), то
      (a) каждая ссылка на столбец, встречающаяся в условии поиска, должна однозначно указывать на столбец таблицы T1 или T2, либо быть внешней ссылкой (ссылкой на столбец запроса более высокого уровня);
      (b) если выражение со значением, непосредственно содержащееся в условии поиска, является спецификацией агрегатной функции, то соединенная таблица должна содержаться в разделе HAVING или списке выборки, и спецификация агрегатной функции должна содержать ссылку на внешний столбец.
  4. Если не указано ни NATURAL, ни спецификация соединения, содержащая только имена столбцов соединения (namedcolumnsjoin), то описатели столбцов результата такие же, как описатели столбцов CP.
  5. Если указано NATURAL или если спецификация запроса содержит только имена столбцов соединения, то
      (a) если указано NATURAL, то пусть именем общего столбца будет имя, являющееся именем столбца для в точности одного столбца T1 и именем столбца для в точности одного столбца T2. Столбцами соединения являются все столбцы T1 и T2 с общими именами;
      (b) если указаны имена столбцов соединения, то каждое имя в этом списке имен должно быть именем столбца для в точности одного столбца T1 и именем столбца для в точности одного столбца T2. Пусть именем общего столбца является имя каждого такого столбца. Столбцами соединения являются столбцы T1 и T2, идентифицированные в списке столбцов соединения (joincolumnlist);
      (c) пусть C1 и C2 пара соответствующих столбцов соединения из T1 и T2. Типы данных, на которых определены эти столбцы, должны быть совместимы;
      (d) пусть SLCC - список выборки порожденных столбцов в форме COALESCE (TA.C, TB.C) ASC (см. п.3.2.4) для каждого столбца соединения в том порядке, в котором они появляются в T1;
      (e) пусть SL1 - список выборки столбцов T1, не являющихся столбцами соединения, в том порядке, в котором они появляются в T1, а SL2 - аналогичный список для T2;
      (f) описатели столбцов результата соединенной таблицы такие же, как описатели столбцов результата запроса SELECTSLCC, SLT1, SLT2 FROMTR1, TR2.
  6. Каждый столбец CR результата соединенной таблицы, который не является столбцом соединения и соответствует столбцу C1 таблицы T1, потенциально может содержать неопределенные значения, если выполняется любое из следующих условий:
      (a) специфицировано RIGHT, FULL или UNION;
      (b) специфицировано INNER, LEFT или CROSSJOIN, и столбец С1 потенциально может содержать неопределенные значения.
  7. Каждый столбец CR результата соединенной таблицы, который не является столбцом соединения и соответствует столбцу C2 таблицы T2, потенциально может содержать неопределенные значения, если выполняется любое из следующих условий:
      (a) специфицировано LEFT, FULL или UNION;
      (b) специфицировано INNER, RIGHT или CROSSJOIN, и столбец С2 потенциально может содержать неопределенные значения.
  8. Каждый столбец CR результата соединенной таблицы, который является столбцом соединения и соответствует столбцам C1 таблицы T1 и C2 таблицы T2, потенциально может содержать неопределенные значения, если выполняется любое из следующих условий:
      (a) специфицировано RIGHT, FULL или UNION и столбец C1 потенциально может содержать неопределенные значения;
      (b) специфицировано LEFT, FULL или CROSSJOIN, и столбец С2 потенциально может содержать неопределенные значения.
  9. Соединенная таблица является только читаемой.
  10. Определим T следующим образом:
      (a) если тип соединения есть UNION, то пусть T будет пустым множеством;
      (b) если специфицировано CROSSJOIN, то пусть T будет мультимножеством строк CP;
      (c) если задано условие соединения, то пусть T будет мультимножеством строк CP, для которых заданное условие поиска вычисляется в true;
      (d) если указаны NATURAL или имена столбцов соединения, то
      (i) если имеются столбцы соединения, то пусть T будет мультимножеством строк CP, для которых соответствующие столбцы соединения имеют одинаковые значения;
      (ii) в противном случае пусть T будет мультимножеством строк CP.
  11. Пусть P1 - мультимножество строк из T1, для которых в T существует некоторая строка, являющаяся конкатенацией некоторой строки R1 из P1 и некоторой строки R2 из T2. Пусть P2 - мультимножество строк из T2, для которых в T существует некоторая строка, являющаяся конкатенацией некоторой строки R1 из T1 и некоторой строки R2 из P2.
  12. Пусть мультимножество U1 составляют те строки из T1, которые не входят в P1, а U2 - строки, которые не входят в P2.
  13. Пусть D1 и D2 - степени T1 и T2 соответственно. Пусть X1 получается из U1 путем расширения вправо на D2 столбцов, содержащих неопределенные значения, а X2 - из U2 путем расширения влево на D1 столбцов, содержащих неопределенные значения.
  14. Результат соединенной таблицы S получается следующим образом:
      (a) если задано INNER или CROSSJOIN, то S - мультимножество строк из T.
      (b) если указано LEFT, то S - это мультимножество строк, вырабатываемое в результате следующего запроса:
      SELECT * FROMT 
                
      UNIONALL
      SELECT * FROMX1

      (c) если указано RIGHT, то S - это мультимножество строк, вырабатываемое в результате следующего запроса:

      SELECT * FROMT 
                
      UNIONALL
      SELECT * FROMX2

      (d) если указано FULL, то S - это мультимножество строк, вырабатываемое в результате следующего запроса:

      SELECT * FROMT 
                
      UNIONALL
      SELECT * FROMX1
      UNIONALL
      SELECT * FROMX2

      (e) если указано UNION, то S - это мультимножество строк, вырабатываемое в результате следующего запроса:

      SELECT * FROMX1 
                
      UNIONALL
      SELECT * FROMX2
  15. Если указаны NATURAL или список имен столбцов соединения, то окончательный результат соединенной таблицы - это мультимножество строк из S, получаемое в результате выполнения следующего запроса: SELECTSLCC, SL1, SL2 FROMS. В противном случае окончательным результатом является S.

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

В стандарте SQL/92 специфицированы три вида подзапросов: скалярный, строчный и табличный. Скалярный подзапрос выдает одно значение некоторого типа; строчный подзапрос выдает одну строку; табличный подзапрос выдает таблицу. В основе каждого вида подзапроса лежит табличное выражение. Синтаксически соответствующие конструкции определяются следующими правилами:

<scalar subquery> ::= <subquery> 
    
<row subquery> ::= <subquery>
<table subquery> ::= <subquery>
<subquery> ::= <left paren> <query expression> <right paren>

Пояснения:

  1. Степень скалярного подзапроса должна быть равна 1.
  2. Степень строчного подзапроса должна быть больше 1.
  3. Тип данных скалярного подзапроса совпадает с типом данных соответствующего столбца выражения запросов.
  4. Типы данных столбцов строчного или табличного подзапроса совпадают с типами данных соответствующих столбцов выражения запросов.
  5. Если мощность скалярного или строчного подзапроса больше 1, то возбуждается исключительное условие.

Теперь мы в состоянии привести синтаксические определения и соответствующие пояснения по поводу выражения запросов:

<query expression> ::= 
    
<non-join query expression>
|<joined table>
<non-join query expression> ::=
<non-join query term>
|<query expression> UNION [ ALL ]
[ <corresponding spec> ]
|<query term> <query expression> EXCEPT [ ALL ]
[ <corresponding spec> ] <query term>
<query term> ::=
<non-join query term>
|<joined table>
<non-join query term> ::=
<non-join query primary>
|<query term> INTERSECT [ ALL ]
[ <corresponding spec> ] <query primary>
<query primary> ::=
<non-join query primary>
|<joined table>
<non-join query primary> ::=
<simple table>
|<left paren> <non-join query expression> <right paren>
<simple table> ::=
<query specification>
|<table value constructor>
|<explicit table>
<explicit table> ::= TABLE <table name>
<corresponding spec> ::=
CORRESPONDING
[ BY <left paren> <corresponding column list> <right paren> ]
<corresponding column list> ::= <column name list>

Пояснения:

  1. Если в терме или выражении запросов без соединения присутствует теоретико-множественный оператор, то пусть T1, T2 и TR обозначают соответственно первый операнд, второй операнд и результат терма или выражения, а OP - используемую теоретико-множественную операцию.
  2. Если специфицировано CORRESPONDING, то
      (a) одно имя столбца не должно быть специфицировано более одного раза для столбцов T1 и T2;
      (b) по крайней мере один столбец T1 должен иметь имя, являющееся именем некоторого столбца T2;
      (c) если список соответствия столбцов не задан, пусть SL обозначает список выборки с указанием имен столбцов, являющихся именами столбцов и в T1, и в T2, в том порядке, в котором эти имена фигурируют в T1;
      (d) если список соответствия столбцов задан, то пусть SL обозначает список выборки с указанием тех имен столбцов, явно входящих в список соответствия, в том порядке, в котором эти имена фигурируют в списке соответствия; каждое имя столбца в списке соответствия должно быть именем столбца и T1, и T2;
      (e) терм или выражение запросов без соединения эквивалентны следующему:
      (SELECTSLFROMTN1) OP (SELECTSLFROMTN2). 
                
  3. Если CORRESPONDING не указано, то T1 и T2 должны быть одинаковой степени.
  4. Если не задан теоретико-множественный оператор, то результатом вычисления выражения запросов является результат вычисления простой или соединенной таблицы.
  5. Если теоретико-множественный оператор задан, то результатом его применения является таблица, содержащая следующие строки:
      (a) пусть R - строка, являющаяся дубликатом некоторой строки T1 или некоторой строки T2 или обоих; пусть m - число дубликатов R в T1, а n - число дубликатов R в T2;
      (b) если специфицировано ALL, то
      (i) если указана операция UNION, то число дубликатов R в T равно m + n;
      (ii) если указана операция EXCEPT, то число дубликатов R в T равно max ((m-n),0);
      (iii) если указана операция INTERSECT, то число дубликатов R в T равно min (m,n).

4. Допустимые предикаты и условия поиска

Внешне предикаты, которые можно использовать в условиях поиска SQL/92, очень похожи на предикаты SQL/89. Но, во-первых, ассортимент допустимых предикатов расширен, а во-вторых, возможности задания условий "старых" предикатов стали существенно шире. Поэтому мы перечислим все возможные предикаты с приведением их синтаксиса и кратких пояснений. В конце раздела будут приведены правила формулировки и семантика условий поиска.

Предикат позволяет специфицировать условие, результатом вычисления которого может быть true, false или unknown. В языке SQL/92 допустимы следующие предикаты:

<predicate> ::= 
    
<comparison predicate>
|<between predicate>
|<in predicate>
|<like predicate>
|<null predicate>
|<quantified comparison predicate>
|<exists predicate>
|<unique predicate>
|<match predicate>
|<overlaps predicate>

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

В SQL/92 этот предикат предназначен для спецификации сравнения двух строчных значений. Синтаксис предиката следующий:

<comparison predicate> ::= 
    
<row value constructor> <comp op> <row value constructor>
<comp op> ::=
<equals operator>
|<not equals operator>
|<less than operator>
|<greater than operator>
|<less than or equals operator>
|<greater than or equals operator>

Пояснения:

  1. Строки-операнды должны быть одинаковой степени.
  2. Типы данных соответствующих значений строк-операндов должны быть совместимы.
  3. Пусть X и Y обозначают соответствующие элементы строк-операндов, а XV и YV - их значения
      (a) если XV и/или YV являются неопределенными значениями, то значение условия "X <compop> Y" есть unknown;
      (b) если XV и YV не являются неопределенными значениями, то значением условия "X <compop> Y" является true или false в соответствии с естественными правилами применения операции сравнения.
  4. Числа сравниваются в соответствии с алгебраическими значениями.
  5. Сравнение двух текстовых строк производится следующим образом:
      (a) если длина в символах строки X не равна длине строки Y, то для выравнивания длин строк более короткая строка расширяется символом набивки (padsymbol); если не используется явно специфицируемый порядок сортировки для используемого набора символов, то в качестве символа набивки используется пробел;
      (b) далее производится лексикографическое сравнение строк в соответствии с предопределенным или явно определенным порядком сортировки символов.
  6. Сравнение двух битовых строк X и Y основано на сравнении соответствующих бит. Если Xi и Yi - значения i-тых бит X и Y соответственно и если LX и LY обозначает длину в битах X и Y соответственно, то
      (a) X равно Y тогда и только тогда, когда LX = LY и Xi = Yi для всех i;
      (b) X меньше Y тогда и только тогда, когда
      (i) LX < LY и Xi = Yi для всех i меньших или равных LX, или
      (ii) Xi = Yi для всех i < n и Xn = 0, а Yn =1 для некоторого n меньшего или равного min (LX,LY).
  7. Сравнение двух значений типа дата-время производится в соответствии с видом интервала, получающегося при вычитании второго значения из первого. Пусть X и Y - сравниваемые значения, а H - наименее значимое поле даты-времени X и Y. Результат сравнения X <compop> Y определяется как (X - Y) H <compop> INTERVAL (0) H. (Два значения типа дата-время сравнимы только в том случае, если они содержат одинаковый набор полей даты-времени.)
  8. Пусть Rx и Ry обозначают строки-операнды, а RXi и RXi - i-тые элементы Rx и Ry соответственно. Результат сравнения "Rx <compop> Ry" определяется следующим образом:
      (a) "Rx = Ry" есть true тогда и только тогда, когда RXi = RYi для всех i;
      (b) "Rx <> Ry" есть true тогда и только тогда, когда RXi <> RYi для некоторого i;
      (c) "Rx < Ry" есть true тогда и только тогда, когда RXi = RYi для всех i < n, и RXn < RYn для некоторого n;
      (d) "Rx > Ry" есть true тогда и только тогда, когда RXi = RYi для всех i < n, и RXn > RYn для некоторого n;
      (e) "Rx <= Ry" есть true тогда и только тогда, когда Rx = Ry или Rx < Ry;
      (f) "Rx >= Ry" есть true тогда и только тогда, когда Rx = Ry или Rx > Ry;
      (g) "Rx = Ry" есть false тогда и только тогда, когда "Rx <> Ry" есть true.
      (h) "Rx <> Ry" есть false тогда и только тогда, когда "Rx = Ry" есть true.
      (i) "Rx < Ry" есть false тогда и только тогда, когда "Rx >= Ry" есть true.
      (j) "Rx > Ry" есть false тогда и только тогда, когда "Rx <= Ry" есть true.
      (k) "Rx <= Ry" есть false тогда и только тогда, когда "Rx > Ry" есть true.
      (l) "Rx >= Ry" есть false тогда и только тогда, когда "Rx < Ry" есть true.
      (m) "Rx <compop> Ry" есть unknown тогда и только тогда, когда "Rx <compop> Ry" не есть true или false.

4.2. Предикат between

Как и в SQL/89, предикат позволяет специфицировать условие вхождения в диапазон значений, но в SQL/92 операндами являются строки:

<between predicate> ::= 
    
<row value constructor> [ NOT ] BETWEEN
<row value constructor> AND <row value constructor>

Пояснения:

  1. Все три строки-операнды должны иметь одну и ту же степень.
  2. Типы данных соответствующих значений строк-операндов должны быть совместимыми.
  3. Пусть X, Y и Z обозначают первый, второй и третий операнды.
  4. "XNOTBETWEENYANDZ" эквивалентно "NOT (XBETWEENYANDZ)".
  5. "XBETWEENYANDZ" эквивалентно "X>=YANDX<=Z".

4.3. Предикат in

Предикат позволяет специфицировать условие вхождения строчного значения в указанное множество значений. Синтаксические правила следующие:

<in predicate> ::= 
    
<row value constructor>
[ NOT ] IN <in predicate value>
<in predicate value> ::=
<table subquery>
|<left paren> <in value list> <right paren>
<in value list> ::=
<value expression> { <comma> <value expression> }...

Пояснения:

  1. Пусть IVL обозначает список включаемых значений (<invaluelist>). Тогда (IVL) эквивалентно конструктору табличного значения (VALUESIVL).
  2. Пусть RVC обозначает строку-первый операнд, а IPV - множество значений (<inpredicatevalue>.
  3. Выражение RVCNOTINIPV эквивалентно NOT (RVCINIPV).
  4. Выражение RVCINIPV эквивалентно RVC = ANYIPV.

4.4. Предикат like

Формально предикат определяется следующими синтаксическими правилами:

<like predicate> ::= 
    
<match value> [ NOT ] LIKE <pattern>
[ ESCAPE <escape character> ]
<match value> ::= <character value expression>
<pattern> ::= <character value expression>
<escape character> ::= <character value expression>

Пояснения: Если не считать того, что в соответствующем условии можно использовать выражения, вырабатывающие значения типа символьных строк, и того, что для используемого набора символов может быть явно задан порядок сортировки, смысл предиката LIKE в SQL/92 не изменился по сравнению с SQL/89.

4.5. Предикат null

Как и в SQL/89, предикат null позволяет проверить, не является ли значение неопределенным, но теперь в нем можно использовать операнд-строку:

<null predicate> ::= <row value constructor> IS [ NOT ] NULL 
    

Пояснения:

  1. Пусть R обозначает значение строки-операнда.
  2. Если все значения, входящие в R, являются неопределенными, значение условия "RISNULL" есть true; иначе - false.
  3. Если ни одно из значений R не является неопределенным, то значением условия "RISNOTNULL" является true; иначе - false.

Замечание: для всех R условие "RISNOTNULL" имеет то же значение, что условие "NOTRISNULL" в том и только в том случае, когда степень R равна 1. Полная семантика предиката null приведена в следующей таблице:

УсловиеRISNULLRISNOTNULLNOTRISNULLNOTRISNOTNULL
Степень 1: nulltruefalsefalsetrue
Степень 1: notnullfalsetruetruefalse
Степень > 1: все nulltruefalsefalsetrue
degree > 1: есть nullfalsefalsetruetrue
degree > 1: нет nullfalsetruetruefalse

4.6. Предикат сравнения с квантором

Этот предикат позволяет специфицировать квантифицированное сравнение строчного значения и определяется следующими синтаксическими правилами:

<quantified comparison predicate> ::= 
    
<row value constructor>
<comp op> <quantifier> <table subquery>
<quantifier> ::= <all> <some>
<all> ::= ALL
<some> ::= SOME ANY

Пояснения:

  1. Степень первого операнда должна быть такой же, как и степень табличного подзапроса.
  2. Типы данных значений строки-операнда должны быть совместимы с типами данных соответствующих столбцов табличного подзапроса.
  3. Сравнение строк производится по тем же правилам, что и для предиката сравнения (п. 3.4.1).
  4. В остальном вычисление условий с кванторами some и all производится так же, как для предиката с квантором в языке SQL/89.

4.7. Предикат exists

Этот предикат имеет тот же смысл, что и соответствующий предикат языка SQL/89, но теперь его операндом может быть табличный подзапрос:

<exists predicate> ::= EXISTS <table subquery> 
    

Пояснение: Если мощность табличного подзапроса больше нуля, то значение соответствующего условия есть true; иначе - false.

4.8. Предикат unique

Этот предикат позволяет сформулировать условие отсутствия дубликатов в результате запроса:

<unique predicate> ::= UNIQUE <table subquery> 
    

Пояснение: результат вычисления условия UNIQUE <tablesubquery> есть true, если в таблице-результате вычисления табличного подзапроса нет таких двух строк, что значение каждого столбца одной строки не является неопределенным и равным значению соответствующего столбца второй строки; в противном случае значение условия есть false.

4.9. Предикат match

Предикат позволяет сформулировать условие соответствия строчного значения результату табличного подзапроса. Синтаксис определяется следующим правилом:

<match predicate> ::= 
    
<row value constructor>
MATCH [ UNIQUE ] [ PARTIAL FULL ] <table subquery>

Пояснения:

  1. Степень первого операнда должна совпадать со степенью табличного подзапроса.
  2. Типы данных первого операнда должны быть совместимы с типами соответствующих столбцов табличного подзапроса.
  3. Сравнение пар соответствующих значений производится аналогично тому, как это специфицировалось для предиката сравнения.
  4. Пусть R обозначает строку-первый операнд.
  5. Если не указано ни PARTIAL, ни FULL, то
      (a) если некоторое значение в R является неопределенным, то значением условия является true;
      (b) если в R нет неопределенных значений, то
      (i) если не указано UNIQUE и существует (возможно, не уникальная) строка RTi в результате табличного подзапроса такая, что R = RTi, то значение условия есть true;
      (ii) если указано UNIQUE и в результате табличного подзапроса существует уникальная строка RTi такая, что R = RTi, то значение условия есть true;
      (iii) в противном случае значением условия является false.
  6. Если указано PARTIAL, то
      (a) если все значения в R неопределенные, то значение условия есть true;
      (b) иначе:
      (i) если не указано UNIQUE и в результате табличного подзапроса существует (возможно, не уникальная) строка RTi такая, что каждое отличное от неопределенного значение R равно соответствующему значению RTi, то значение условия есть true;
      (ii) если указано UNIQUE и в табличном подзапросе существует уникальная строка RTi такая, что каждое отличное от неопределенного значение R равно соответствующему значению RTi, то значение условия есть true;
      (iii) в противном случае значение условия есть false.
  7. Если указано FULL, то
      (a) если все значения в R неопределенные, то значение условия есть true.
      (b) если в R нет неопределенных значений, то
      (i) если не указано UNIQUE и в результате табличного подзапроса существует (возможно, не уникальная) строка RTi такая, что R = RTi, то значение условия есть true;
      (ii) если указано UNIQUE и в результате табличного подзапроса существует уникальная строка RTi такая, что R = RTi, то значение условия есть true;
      (iii) в противном случае значение условия есть false;
      (c) в противном случае значение условия есть false.

4.10. Предикат overlaps

Этот предикат служит для проверки перекрытия во времени двух событий. Условие определяется следующим синтаксисом:

<overlaps predicate> ::= 
    
<row value constructor 1> OVERLAPS
<row value constructor 2>
<row value constructor 1> ::= <row value constructor>
<row value constructor 2> ::= <row value constructor>

Пояснения:

  1. Степень каждой из строк-операндов должна быть равна 2.
  2. Тип данных первого столбца каждого из операндов должен быть типом даты-времени, и типы данных первых столбцов должны быть совместимы.
  3. Тип данных второго столбца каждого из операндов должен быть типом даты-времени или интервала.
      (a) если это тип интервала, то точность типа должна быть такой, чтобы интервал можно было прибавить к значению типа дата-время первого столбца;
      (b) если это тип дата-время, то он должен быть совместим с типом данных дата-время первого столбца.
  4. Пусть D1 и D2 обозначают значения первого столбца первого и второго операндов соответственно.
  5. Если второй столбец первого операнда имеет тип дата-время, то пусть E1 обозначает его значение.
  6. Если второй столбец первого операнда имеет тип INTERVAL, то пусть I1 обозначает его значение, а E1 = D1 + I1.
  7. Если D1 - неопределенное значение или если E1 < D1, то пусть S1 = E1 и T1 = D1. Иначе, пусть S1 = D1 и T1 = E1.
  8. Аналогично определяются S2 и T2 применительно ко второму операнду.
  9. Результат условия совпадает с результатом вычисления следующего выражения:
(S1 > S2 ANDNOT (S1 >= T2 ANDT1 >= T2)) 
    
OR
(S2 > S1 ANDNOT (S2 >= T1 ANDT2 >= T1))
OR
(S1 = S2 AND (T1 <> T2 ORT1 = T2))

4.11. Условие поиска

Условие поиска принимает значения true, false или unknown в зависимости от результата применения булевских операторов к составляющим его простым условиям. Синтаксис и семантика условия поиска в SQL/92 практически такие же, как в SQL/89, но в стандарте SQL/92 более четко специфицирована трехзначная логика, в которой происходит вычисление условия поиска. Синтаксис определяется следующими правилами:

<search condition> ::= 
    
<boolean term>
|<search condition> OR <boolean term>
<boolean term> ::=
<boolean factor>
|<boolean term> AND <boolean factor>
<boolean factor> ::= [ NOT ] <boolean test>
<boolean test> ::=
<boolean primary> [ IS [ NOT ] <truth value> ]
<truth value> ::=
TRUE
|FALSE
|UNKNOWN
<boolean primary> ::=
<predicate>
| <left paren> <search condition> <right paren>

Пояснения:

  1. Если условие поиска не содержит булевских операторов, то результат его вычисления совпадает с результатом составляющего его простого условия, задаваемого одним из перечисленных выше предикатов.
  2. NOT(true) есть false, NOT(false) есть true и NOT(unknown) есть unknown. Правила применения других булевских операторов задаются следующими таблицами истинности:

Таблица истинности для оператора AND

 truefalseunknown
truetruefalseunknown
falsefalsefalsefalse
unknownunknownfalseunknown

Таблица истинности для оператора OR

 truefalseunknown
truetruetruetrue
falsetruefalseunknown
unknowntrueunknownunknown

Таблица истинности для оператора IS
 truefalseunknown
truetruetruefalse
falsefalsetruefalse
unknownfalsefalseunknown



Продолжение в статье Язык баз данных SQL/92 часть 3

© WIKI.RU, 2008–2017 г. Все права защищены.