Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
VPS в 21 локации

От 104 рублей в месяц

Безлимитный трафик. Защита от ДДоС.

🔥 VPS до 5.7 ГГц под любые задачи с AntiDDoS в 7 локациях

💸 Гифткод CITFORUM (250р на баланс) и попробуйте уже сейчас!

🛒 Скидка 15% на первый платеж (в течение 24ч)

Скидка до 20% на услуги дата-центра. Аренда серверной стойки. Colocation от 1U!

Миграция в облако #SotelCloud. Виртуальный сервер в облаке. Выбрать конфигурацию на сайте!

Виртуальная АТС для вашего бизнеса. Приветственные бонусы для новых клиентов!

Виртуальные VPS серверы в РФ и ЕС

Dedicated серверы в РФ и ЕС

По промокоду CITFORUM скидка 30% на заказ VPS\VDS

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, … C120), то в результате выполнения раздела FROM образуется таблица (назовем ее 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, содержащая те и только те группы строк таблицы 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.

В случае (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 теперь можно использовать и выражение со значением-мультимножеством. Однако в этом курсе мы не будем подробно рассатривать эту возможность.

Назад Содержание Вперёд

VPS/VDS серверы. 30 локаций на выбор

Серверы VPS/VDS с большим диском

Хорошие условия для реселлеров

4VPS.SU - VPS в 17-ти странах

2Gbit/s безлимит

Современное железо!

Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

✅ Дешевый VPS-хостинг на AMD EPYC: 1vCore, 3GB DDR4, 15GB NVMe всего за €3,50!

🔥 Anti-DDoS защита 12 Тбит/с!

Новости мира IT:

Архив новостей

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 7861149
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...