Open Library - открытая библиотека учебной информации

Открытая библиотека для школьников и студентов. Лекции, конспекты и учебные материалы по всем научным направлениям.

Категории

Дом Табличное выражение, спецификация запроса и выражение запросов
просмотров - 241

Табличным выражением (table_expression) принято называть конструкция

table_expression ::= FROM table_reference_commalist [ WHERE conditional_expression ] [ GROUP BY column_name_commalist ] [ HAVING conditional_expression ]

Спецификацией запроса (query_specification) принято называть конструкция

query_specification SELECT [ ALL | DISTINCT ] select_item_commalist table_expression

Наконец, выражением запросов (query_expression) принято называть конструкция

query_expression ::= [ with_clause ] query_expression_body

query_expression_body ::= { non_join_query_expression | joined_table }

non_join_query_expression ::= non_join_query_term | query_expression_body { UNION | EXCEPT }[ ALL | DISTINCT ] [ corresponding_spec ] query_term

query_term ::= non_join_query_term | joined_table

non_join_query_term ::= non_join_query_primary | query_term INTERSECT [ ALL | DISTINCT ] [ corresponding_spec ] query_primary

query_primary ::= non_join_query_primary | joined_table

non_join_query_primary ::= simple_table | (non_join_query_expression)

simple_table ::= query_specification | table_value_constructor | TABLE table_name

corresponding_spec ::= CORRESPONDING [ BY column_name_comma_list ]

В случае если не обращать внимание на не обсуждавшиеся пока конструкции joined_table и table_value_constructor, синтаксические правила показывают, что выражение запросов строится из выражений, значениями которых являются таблицы, с использованием “теоретико-множественных”* операций UNIOIN (объединœение), EXCEPT (вычитание) и INTERSECT (пересечение). Операция пересечения является “мультипликативной” и обладает приоритетом, большим приоритета “аддитивных” операций объединœения и вычитания. Вычисление выражения производится слева направо с учетом приоритетов операций и круглых скобок. При этом действуют следующие правила.

Ø В случае если выражение запросов не включает ни одной теоретико-множественной операции, то результатом вычисления выражения запросов является результат вычисления простой или соединœенной таблицы.

Ø В случае если в терме (non_join_query_term) или выражении запросов (non_join_query_expression) без соединœения присутствует теоретико-множественная операция, то пусть T1, T2 и TR обозначают соответственно первый операнд, второй операнд и результат терма или выражения соответственно, а OP – используемую теоретико-множественную операцию.

Ø В случае если в операции присутствует специфицикация CORRESPONDING, то

(a) если присутствует конструкция BY column_name_comma_list, то всœе имена в этом списке должны быть различны, и каждое имя должно являться одновременно именем некоторого столбца таблицы T1 и именем некоторого столбца таблицы T2, причем типы этих столбцов должны быть совместимыми; обозначим данный список имен через SL.

(b) если список соответствия столбцов не задан, пусть SL обозначает список имен столбцов, являющихся именами столбцов и в T1, и в T2, в том порядке, в котором эти имена фигурируют в T1;

(c) вычисляемые терм или выражение запросов без соединœения эквивалентны выражению (SELECT SL FROM T1) OP (SELECT SL FROM T2), не включающему специфицикация CORRESPONDING.

Ø При отсутствии в операции спецификации CORRESPONDING эта операция выполняется таким образом, как если бы эта спецификация присутствовала и включала конструкцию BY column_name_comma_list, в которой были бы перечислены всœе столбцы таблицы T1.*

Ø При выполнении операции OP две строки s1 с именами столбцов c1, c2, …, cn и s2 с именами столбцов d1, d2, …, dn считаются строками-дубликатами, если для каждого I (i = 1, 2, …, n) либо ci и di не содержат NULL, и (ci = di) = true**, либо и ci, и di содержат NULL.

Ø В случае если в операции OP не задана спецификация ALL, то в TR строки-дубликаты удаляются.

Ø В случае если спецификация ALL задана, то пусть s – строка, являющаяся дубликатом некоторой строки T1, или некоторой строки T2, или обоих; пусть m - число дубликатов s в T1, а n – число дубликатов s в T2. Тогда

· если указана операция UNION, то число дубликатов s в TR равно m + n;

· если указана операция EXCEPT, то число дубликатов s в TR равно max ((m-n),0);

· если указана операция INTERSECT, то число дубликатов s в TR равно min (m,n).

Раздел WITH выражения запросов

Как видно из синтаксиса выражения запросов, в этом выражении может присутствовать раздел WITH. Он задается в следующем синтаксисе:

with_clause ::= WITH [ RECURSIVE ] with_element_comma_list

with_element ::= query_name [ (column_name_list) ] AS (query_expression) [ search_or_cycle_clause ]

Общую форму раздела WITH мы обсудим в следующих лекциях, когда будем рассматривать средства формулировки рекурсивных запросов. Пока ограничимся случаем, когда в разделœе WITH отсутствуют спецификация RECURSIVE и search_or_cycle_clause. Тогда конструкция

WITH query_name (c1, c2, … cn) AS (query_exp_1) query_exp_2

означает, что в любом месте выражения запросов query_exp_2, где допускается появление ссылки на таблицу, можно использовать имя query_name. Можно считать, что перед выполнением query_exp_2 происходит выполнение query_exp_1, и результирующая таблица с именами столбцов c1, c2, … cn сохраняется под именем query_name. Как мы увидим позже, в этом случае раздел WITH фактически служит для локального определœения представляемой таблицы (VIEW).

Конструкторы значения строки и таблицы

Чтобы завершить обсуждение выражений запросов (с учетом того, что конструкция соединœенных таблиц (joined_table) отложена на следующие лекции), нам осталось рассмотреть конструкции table_value_constructor и TABLE table_name.

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

row_value_constructor ::= row_value_constructor_element | [ ROW ] (row_value_constructor_element_comma_list) | row_subquery

row_value_constructor_element ::= value_expression | NULL | DEFAULT

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

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

table_value_constructor ::= VALUES row_value_constructor_comma_list

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

Наконец, конструкция TABLE table_name является сокращенной формой записи выражения SELECT * FROM table_name.

Ссылки на базовые, представляемые и порождаемые таблицы

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

table_reference ::= table_primary

table_primary ::= table_or_query_name [ [ AS ] correlation_name [ (derived_column_list) ] ] | derived_table [ AS ] correlation_name [ (derived_column_list) ]

table_or_query_name ::= { table_name | query_name }

derived_table ::= (query_expression)

Итак, в самом простом случае в качестве ссылки на таблицу используется имя таблицы (базовой или представляемой) или имя запроса, присоединœенного к данному запросу с помощью раздела WITH. Во втором случае (derived_table) порождаемая таблица задается выражением запроса, заключенным в круглые скобки. Явное указание имен столбов результата запроса из раздела WITH или порождаемой таблицы требуется в том случае, когда эти имена не выводятся явно из соответствующего выражения запроса. Обратите внимание, что в этих случаях в соответствующем элементе списка раздела FROM должен указываться псевдоним (correlation_name), потому что иначе таблица была бы вообще лишена имени. Можно считать, что выражение запроса вычисляется и сохраняется во временной таблице при обработке раздела FROM.

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

Представляемые таблицы, или представления (VIEW)

Еще одним примером рекурсивности спецификаций языка SQL является то, что в конце этой лекции мы вынуждены прервать обсуждение оператора выборки и ввести понятие представляемой таблицы, или представления, которую можно использовать в операторе выборки наряду с базовыми таблицами. Только после этого можно будет считать обсуждение ссылок на таблицы в разделœе FROM сравнительно завершенным. Итак оператор создания представления в общем случае определяется следующими синтаксическими правилами:

create_view ::= CREATE [ RECURSIVE ] VIEW table_name [ column_name_comma_list ] AS query_expression [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]

Рекурсивные представления (такие, в определœении которых присутствует ключевое слово RECURSIVE) и необязательный раздел WITH CHECK OPTION мы обсудим в следующих лекциях (пока лишь заметим, что данный раздел связан с особенностями выполнения операций обновления базы данных через представления). Здесь мы кратко обсудим только простую форму представлений, определяемых по следующим правилам:

create_view ::= CREATE VIEW table_name [ column_name_comma_list ] AS query_expression

Имя таблицы, задаваемое в определœении представления, существует в том же пространстве имен, что и имена базовых таблиц, и, следовательно, должно отличаться от всœех имен таблиц (базовых и представляемых), созданных тем же пользователœем. В случае если имя представления встречается в разделœе FROM какого-либо оператора выборки, то вычисляется выражение запроса, указанное в разделœе AS, и оператор выборки работает с результирующей таблицей этого выражения запроса.* Явное указание имен столбов представляемой таблицы требуется в том случае, когда эти имена не выводятся из соответствующего выражения запроса.

Как и для всœех других вариантов оператора CREATE, для CREATE VIEW имеется обратный оператор DROP VIEW table_name, выполнение которой приводит к отмене определœения представления (реально это выражается в удалении данных о представлении из таблиц-каталогов базы данных). После выполнения операции пользоваться представлением с данным именем становится невозможно.**