2008 г.
Базы данных. Вводный курс
Сергей Кузнецов
Назад Содержание Вперёд
17.3. Общая структура оператора выборки в языке SQL
Для выборки данных в прямом SQL используется оператор SELECT
, возвращающий набор118) из одной или нескольких строк одинаковой структуры и задаваемый в следующем синтаксисе:
SELECT [ ALL | DISTINCT ] select_item_commalist
FROM table_reference_commalist
[ WHERE conditional_expression ]
[ GROUP BY column_name_commalist ]
[ HAVING conditional_expression ]
[ ORDER BY order_item_commalist ]
17.3.1. Семантика оператора выборки
Для начала опишем общую схему выполнения оператора SELECT
в соответствии с предписаниями стандарта.119) Выполнение запроса состоит из нескольких шагов, соответствующих разделам оператора выборки. На первом шаге выполняется раздел FROM
. Если список ссылок на таблицы (table_reference_commalist
) этого раздела соответствует таблицам A
, B
, … C
120), то в результате выполнения раздела FROM
образуется таблица (назовем ее T
), являющаяся расширенным декартовым произведением таблиц A
, B
, …, C
. Если в разделе FROM
указана только одна таблица, то она же и является результатом выполнения этого раздела. Как говорилось в лекции 4, в реляционной алгебре для корректного выполнения операции взятия расширенного декартова произведения отношений в общем случае требуется применение операции переименования атрибутов. Соответствующие возможности переименования столбцов таблиц, указанных в списке раздела FROM
, поддерживаются и в SQL. Альтернативный способ именования столбцов результирующей таблицы T
основывается на использовании квалифицированных имен столбцов. Идея этого подхода (более раннего в истории SQL) заключается в том, что с любой таблицей, ссылка на которую содержится в списке раздела FROM
, можно связать некоторое имя-псевдоним (в стандарте оно называется correlation name
121)). Тогда если с такой таблицей A
связан псевдоним Z
, то в пределах оператора выборки можно ссылаться на любой столбец a
таблицы A
по квалифицированному имени Z.a
. Мы обсудим это подробнее в следующем подразделе. Пока же будем считать, что имена всех столбцов таблицы T
определены и различны.
На втором шаге выполняется раздел WHERE
. Условное выражение (conditional_expression
) этого раздела применяется к каждой строке таблицы T
, и результатом является таблица T1
, содержащая те и только те строки таблицы T
, для которых результатом вычисления условного выражения является true
. (Заголовки таблиц T
и T1
совпадают.) Если раздел WHERE
в операторе выборки отсутствует, то это трактуется как наличие раздела WHERE
true
,122) т. е. T1
содержит те и только те строки, которые содержатся в таблице T
. Обратите внимание на разницу в трактовке логических выражений в операторах выборки и в табличных ограничениях целостности. Логическое выражение раздела WHERE
(и раздела HAVING
) оператора выборки разрешает выборку строки в том и только в том случае, когда результатом вычисления логического выражения на данной строке является true
(значения false
и uknown
не являются разрешающими). Логическое выражение табличного ограничения целостности запрещает наличие строки в таблице в том и только в том случае, когда результатом вычисления логического выражения на данной строке является false
(значения true
и uknown
не являются запрещающими).
Если в операторе выборки присутствует раздел GROUP BY
, то он выполняется на третьем шаге. Каждый элемент списка имен столбцов (column_name_commalist
), указываемого в этом разделе, должен быть одним из имен столбцов таблицы T1
. В результате выполнения раздела GROUP BY
образуется сгруппированная таблица T2
, в которой строки таблицы T1
расставлены в минимальное число групп, таких, что во всех строках одной группы значения столбцов, указанных в списке имен столбцов раздела GROUP BY
(столбцов группировки), одинаковы.123) Заметим, что сгруппированные таблицы не могут являться окончательным результатом оператора выборки. Они существуют только на концептуальном уровне на стадии выполнения запроса, содержащего раздел GROUP BY
.
Если в операторе выборки присутствует раздел HAVING
, то он выполняется на следующем шаге. Условное выражение этого раздела применяется к каждой группе строк таблицы T2
, и результатом является сгруппированная таблица T3
, содержащая те и только те группы строк таблицы T2
, для которых результатом вычисления условного выражения является true
. Условное выражение раздела HAVING
строится по синтаксическим правилам, общим для всех условных выражений, но обладает той спецификой, что применяется к группам строк, а не к отдельным строкам. Поэтому предикаты, из которых строится это условное выражение, должны быть предикатами на группу в целом. В них могут использоваться имена столбцов группировки (инварианты группы) и так называемые агрегатные функции (COUNT
, SUM
, MIN
, MAX
, AVG
) от других столбцов. Мы обсудим агрегатные функции более подробно в лекции 19.
При наличии в запросе раздела HAVING
, которому не предшествует раздел GROUP BY
, таблица T1
рассматривается как сгруппированная таблица, состоящая из одной группы строк, без столбцов группирования. В этом случае логическое выражение раздела HAVING
может состоять только из предикатов с агрегатными функциями, а результат вычисления этого раздела T3
либо совпадает с таблицей T1
, либо является пустым.
Если в операторе выборки присутствует раздел GROUP BY
, но отсутствует раздел HAVING
, то это трактуется как наличие раздела HAVING true
,124) т. е. T3
содержит те и только те группы строк, которые содержатся в таблице T2
.
После выполнения раздела WHERE
(если в запросе отсутствуют разделы GROUP BY
и HAVING
, случай (a)) или явно или неявно заданного раздела HAVING
(случай (b)) выполняется раздел SELECT
. При выполнении этого раздела на основе таблицы T1
в случае (a) или на основе сгруппированной таблицы T3
в случае (b) строится таблица T4
, содержащая столько строк, сколько строк или групп строк содержится в таблицах T1
или T3
соответственно. Число столбцов в таблице T4
зависит от числа элементов в списке элементов выборки (select_item_commalist
) и от вида элементов.
Рассмотрим, каким образом формируются значения столбцов в таблице T4
. Элемент списка выборки может задаваться одним из двух способов:
select_item ::= value_expression [ [ AS ] column_name ]
| [ correlation_name . ] *
Сначала обсудим первый вариант. В этом случае каждый элемент списка элементов выборки соответствует столбцу таблицы T4
. Столбцу может быть явным образом приписано имя (когда и зачем могут использоваться имена таблицы T4
, мы обсудим позже). Порядок формирования значения этого столбца для выделенных выше случаев (a) и (b) различается, и мы рассмотрим подобные случаи по отдельности.
В случае (a) выражение, содержащееся в элементе выборки, может содержать литеральные константы и вызовы функций со значениями соответствующих типов (в том числе ниладические). Кроме того, в выражении могут использоваться имена столбцов таблицы T1
125). Выражение вычисляется для каждой строки таблицы T1
, и именам столбцов соответствуют значения этих столбцов в данной строке таблицы T1
.
В случае (b), как и в случае (a), выражение, содержащееся в элементе выборки, может содержать литеральные константы и вызовы функций. Но, в отличие от случая (a), в выражение могут входить непосредственно имена только тех столбцов таблицы T3
, которые входили в список столбцов группировки раздела GROUP BY
оператора выборки. (Если сгруппированная таблица T3
была образована за счет наличия раздела HAVING
без присутствия раздела GROUP BY
, то в выражении элемента выборки вообще нельзя непосредственно использовать имена столбцов таблицы T3
). Имена других столбцов таблицы T3
могут использоваться только в конструкциях вызова агрегатных функций COUNT
, SUM
, MIN
, MAX
, AVG
. Выражение вычисляется для каждой группы строк таблицы T3
. Именам столбцов, входящих в выражение непосредственно, сопоставляются значения этих столбцов, которые соответствуют данной группе зстрок таблицы T3
.
Во втором варианте спецификация элемента списка выборки вида [ Z. ]*
является сокращенной формой записи списка Z.a1
, Z.a2
, …, Z.an
, где a1
, a2
, …, an
представляет собой полный список имен столбцов таблицы, псевдоним которой Z
.126) Следует сделать три замечания. Во-первых, для именованной таблицы, входящей в список раздела FROM только один раз, можно использовать имя таблицы вместо псевдонима. Во-вторых, во втором варианте спецификации элемента списка выборки можно опустить псевдоним только в том случае, если в разделе FROM указана только одна таблица. В-третьих, в случае (b) второй вариант спецификации элемента выборки допустим только тогда, когда все столбцы таблицы с псевдонимом Z
входят в список столбцов группировки раздела GROUP BY
.
Итак, мы получили таблицу T4
. Если в спецификации раздела SELECT
отсутствует ключевое слово DISTINCT
, или присутствует ключевое слово ALL
, либо отсутствуют и ALL
, и DISTINCT
, то T4
является результатом выполнения раздела SELECT
. В противном случае на завершающей стадии выполнения раздела SELECT
в таблице T4
удаляются строки-дубликаты.
Если в операторе выборки не содержится раздел ORDER BY
, то таблица T4
является результирующей таблицей запроса. Иначе на завершающей стадии выполнения запроса производится сортировка строк таблицы T4
в соответствии со списком элементов сортировки (order_item_commalist
) раздела ORDER BY
. В стандарте SQL:1999 элемент списка элементов сортировки имеет следующую синтаксическую форму:
order_item ::= value_expression [ collate_clause ]
[ { ASC | DESC } ]
Выполнение раздела ORDER BY
производится следующим образом.127) Выбирается первый элемент списка сортировки, и строки таблицы T4
расставляются в порядке возрастания (если в элементе присутствует спецификация ASC
; при отсутствии спецификации ASC/DESC
предполагается наличие ASC
) или в порядке убывания (при наличии спецификации DESC
) в соответствии со значениями выражения, содержащегося в данном элементе, которые вычисляются для каждой строки таблицы T4
. Далее выбирается второй элемент списка сортировки, и в соответствии со значениями заданного в нем выражения и порядка сортировки расставляются строки, которые после первого шага сортировки образовали группы с одинаковым значением выражения первого элемента списка сортировки. Операция продолжается до исчерпания списка элементов сортировки. Результирующий отсортированный список строк является окончательным результатом запроса.
В общем случае выражение, входящее в элемент списка сортировки, основывается на именах столбцов таблицы T4
и именах столбцов таблицы, над которой вычислялся раздел SELECT
(T1
или T3
). Идея состоит в том, что если некоторое выражение могло бы быть использовано в элементе списка выборки, то его можно использовать в элементе списка сортировки. В стандарте SQL:1999 присутствует ряд чисто технических ограничений на вид выражений, допустимых в элементах списка сортировки, если в запросе присутствуют разделы GROUP BY
и/или HAVING
и если в разделе SELECT
присутствует спецификация DISTINCT
. Но в любом случае это выражение может иметь вид a
, где a
– имя столбца таблицы T4
.
Заметим, что в предыдущих версиях стандарта языка SQL, включая SQL/92, элемент списка сортировки определялся следующим синтаксическим правилом:
order_item ::= { column_name | unsigned_integer }
[ { ASC | DESC } ]
В качестве имени столбца (column_name
) можно было использовать любое имя, вводимое для столбца таблицы T4
в элементе списка выборки. Вместо имени столбца можно было использовать его порядковый номер (unsigned_integer
) в списке элементов выборки раздела SELECT
. Как мы видели, в новом стандарте вторая возможность исключена. Доводом является не тот факт, что использование номеров столбцов противоречит реляционной модели. Использование номеров столбцов запрещено, поскольку не давало возможности применять в элементах списка сортировки выражения. Тем не менее, по нашему мнению, возможность использования номеров столбцов в течение долгого времени будет продолжать поддерживаться в коммерческих реализациях SQL, поскольку она применяется во многих существующих приложениях.
17.3.2. Ссылки на таблицы раздела FROM
Напомним, что раздел FROM
оператора выборки определяется синтаксическим правилом
FROM table_reference_commalist
Рассмотрим более подробно, какой вид могут иметь элементы этого списка. Для начала приведем полный набор синтаксических правил SQL:1999, определяющий table_reference
.128)
table_reference ::= table_primary | joined_table
table_primary ::= table_or_query_name [ [ AS ] correlation_name
[ (derived_column_list) ] ]
| derived_table [ [ AS ] correlation_name
[ (derived_column_list) ] ]
| lateral_derived_table [ [ AS ] correlation_name
[ (derived_column_list) ] ]
| collection_derived_table [ [ AS ] correlation_name
[ (derived_column_list) ] ]
| ONLY (table_or_query_name)[ [ AS ] correlation_name
[ (derived_column_list) ] ]
| (joined_table)
table_or_query_name ::= { table_name | query_name }
derived_table ::= (query_expression)
lateral_derived_table ::= LATERAL (query_expression)
collection_derived_table ::= UNNEST
(collection_value_exression) [ WITH ORDINALITY ]
Мы отложим до лекции 19 обсуждение порождаемых таблиц с горизонтальной связью (lateral_derived_table
) и «соединенных таблиц» (joined_table
). Кроме того, мы не будем рассматривать в этом курсе конструкции collection_derived_table
и ONLY
(table_or_query_name
), поскольку они относятся к объектным расширениям языка SQL, которые в данном курсе подробно не рассматриваются (на неформальном уровне объектно-реляционный подход обсуждается в лекции 23). Но даже при таких самоограничениях для дальнейшего продвижения нам придется определить несколько дополнительных синтаксических конструкций языка SQL.
118 Мы сознательно используем здесь термин набор, поскольку в обем случае результатом выполнения оператора выборки не является таблица.
119 Не следует понимать эту схему таким образом, что запросы к SQL-ориентированной базе данных действительно должны выполняться именно таким образом. Более того, ни одна реализация SQL не придерживается в точности этой схеме. Но как бы реально не выполнялся оператор выборки, результат должен быть таким же, как если бы он получался при точном следовании описываемой схеме выполнения.
120 A
, B
и C
не обязаны являться базовыми таблицами. См. следующий подраздел.
121 Причины тспользования в стандарте этого термина будут более понятны после ознакомления в следующей лекции с механихмом коррелирующих вложенных подзапросов.
122 Заметим, что эта форма раздела WHERE
в языке SQL не допускается, поскольку после ключевого слова WHERE
должно следовать булевское выражение, а true
булевским выражением не является.
123 Если говорить более точно, то в одной группе все строки, составленные из значений столбцов группировки, являются дубликатами.
124 Заметим, что эта форма раздела HAVING
в языке SQL не допускается, поскольку после ключевого слова HAVING
должно следовать булевское выражение, а true
булевским выражением не является.
125 Обратите внимание, что в выражении элемента выборки не обязательно должно содержаться хотя бы одно имя столбца. Допускается наличие чисто контактного выражения, значение которого будет повторяться в данном столбце всех строк таблицы TF. Кроме того, заметим, что в соответствии с определением value_expression
элемент списка выборки может быть заросом, возвращающим таблицу из одной строки с одним столбцом.
126 Заметим, что любой элемент Z.ai
этого неявно заданного списка может быть явно включен в список элементов выборки. Кстати, если в списке выборки присутствует явно или неявно заданный элемент вида Z.a
, то в пределах запроса соответствующий столбец таблицы T4
получает тоже имя.
127 Мы снова проигнорируем спецификацию раздела collate, связанную с использованием наиональных наборов символов.
128 В связи с введением в стандарте SQL:2003 конструктора типов мультимножеств, в кчестве элемента списка ссылок на таблицы раздела FORM
теперь можно использовать и выражение со значением-мультимножеством. Однако в этом курсе мы не будем подробно рассатривать эту возможность.
Назад Содержание Вперёд