Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Базы данных.doc
Скачиваний:
114
Добавлен:
16.03.2016
Размер:
5.67 Mб
Скачать

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, …C120), то в результате выполнения разделаFROMобразуется

118 Мы сознательно используем здесь термин набор, поскольку в обем случае результатом выполнения оператора выборки не является таблица.

119 Не следует понимать эту схему таким образом, что запросы к SQL-ориентированной базе данных действительно должны выполняться именно таким образом. Более того, ни одна реализация SQL не придерживается в точности этой схеме. Но как бы реально не выполнялся оператор выборки, результат должен быть таким же, как если бы он получался при точном следовании описываемой схеме выполнения.

120 A, B и C не обязаны являться базовыми таблицами. См. следующий подраздел.

таблица (назовем ееT), являющаяся расширенным декартовым произведением таблицA,B, …,C. Если в разделеFROMуказана только одна таблица, то она же и является результатом выполнения этого раздела. Как говорилось в лекции 4, в реляционной алгебре для корректного выполнения операции взятия расширенного декартова произведения отношений в общем случае требуется применение операции переименования атрибутов. Соответствующие возможности переименования столбцов таблиц, указанных в списке разделаFROM, поддерживаются и в SQL. Альтернативный способ именования столбцов результирующей таблицыTосновывается на использовании квалифицированных имен столбцов. Идея этого подхода (более раннего в истории SQL) заключается в том, что с любой таблицей, ссылка на которую содержится в списке разделаFROM, можно связать некоторое имя-псевдоним (в стандарте оно называетсяcorrelation name121)). Тогда если с такой таблицей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, содержащая те и только те группы

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

122 Заметим, что эта форма раздела WHERE в языке SQL не допускается, поскольку после ключевого слова WHERE должно следовать булевское выражение, а true булевским выражением не является.

123 Если говорить более точно, то в одной группе все строки, составленные из значений столбцов группировки, являются дубликатами.

строк таблицы 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) выражение, содержащееся в элементе выборки, может содержать литеральные константы и вызовы функций со значениями соответствующих типов (в том числе ниладические). Кроме того, в выражении могут использоваться имена столбцов таблицыT1125). Выражение вычисляется для каждой строки таблицыT1, и именам столбцов соответствуют значения этих столбцов в данной строке таблицыT1.

124 Заметим, что эта форма раздела HAVING в языке SQL не допускается, поскольку после ключевого слова HAVING должно следовать булевское выражение, а true булевским выражением не является.

125 Обратите внимание, что в выражении элемента выборки не обязательно должно содержаться хотя бы одно имя столбца. Допускается наличие чисто контактного выражения, значение которого будет повторяться в данном столбце всех строк таблицы TF. Кроме того, заметим, что в соответствии с определением value_expression элемент списка выборки может быть заросом, возвращающим таблицу из одной строки с одним столбцом.

В случае (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. Далее выбирается второй элемент списка сортировки, и в соответствии со значениями заданного в нем выражения и порядка сортировки расставляются строки, которые после первого шага сортировки образовали

126 Заметим, что любой элемент Z.ai этого неявно заданного списка может быть явно включен в список элементов выборки. Кстати, если в списке выборки присутствует явно или неявно заданный элемент вида Z.a, то в пределах запроса соответствующий столбец таблицы T4 получает тоже имя.

127 Мы снова проигнорируем спецификацию раздела collate, связанную с использованием наиональных наборов символов.

группы с одинаковым значением выражения первого элемента списка сортировки. Операция продолжается до исчерпания списка элементов сортировки. Результирующий отсортированный список строк является окончательным результатом запроса.

В общем случае выражение, входящее в элемент списка сортировки, основывается на именах столбцов таблицы 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, поскольку она применяется во многих существующих приложениях.