Замок Дракона
![]()
Язык допускает три типа синтаксических конструкций, начинающихся с ключевого слова SELECT: спецификация курсора (cursor specification), оператор выборки (select statement) и подзапрос (subquery). Основой всех них является синтаксическая конструкция «табличное выражение (table expression)». Семантика табличного выражения состоит в том, что на основе последовательного применения разделов from, where, group by и having из заданных в разделе from таблиц строится некоторая новая результирующая таблица, порядок следования строк которой не определен и среди строк которой могут находиться дубликаты (т.е. в общем случае таблица-результат табличного выражения является мультимножеством строк). На самом деле именно структура табличного выражения наибольшим образом характеризует структуру запросов языка SQL/89. Мы рассмотрим ниже структуру и смысл разделов табличного выражения ниже, но до этого немного подробнее обсудим три упомянутые конструкции, включающие табличные выражения.
15.1.1. Спецификация курсора
Наиболее общей является конструкция «спецификация курсора». Курсор — это понятие языка SQL, позволяющее с помощью набора специальных операторов получить построчный доступ к результату запроса к БД. К табличным выражениям, участвующим в спецификации курсора, не предъявляются какие-либо ограничения. Как видно из сводки синтаксических правил, при определении спецификации курсора используются три дополнительных конструкции: спецификация запроса, выражение запросов и раздел ORDER BY.
Спецификация запроса
В спецификации запроса задается список выборки (список арифметических выражений над значениями столбцов результата табличного выражения и констант). В результате применения списка выборки к результату табличного выражения производится построение новой таблицы, содержащей то же число строк, но вообще говоря другое число столбцов, содержащих результаты вычисления соответствующих арифметических выражений из списка выборки. Кроме того, в спецификации запроса могут содержаться ключевые слова ALL или DISTINCT. При наличии ключевого слова DISTINCT из таблицы, полученной применением списка выборки к результату табличного выражения, удаляются строки-дубликаты; при указании ALL (или просто при отсутствии DISTINCT) удаление строк-дубликатов не производится.
Выражение запросов
Выражение запросов — это выражение, строящееся по указанным синтаксическим правилам на основе спецификаций запросов. Единственной операцией, которую разрешается использовать в выражениях запросов, является операция UNION (объединение таблиц) с возможной разновидностью UNION ALL. К таблицам-операндам выражения запросов предъявляется то требование, что все они должны содержать одно и то же число столбцов, и соответствующие столбцы всех операндов должны быть одного и того же типа. Выражение запросов вычисляется слева направо с учетом скобок. При выполнении операции UNION производится обычное теоретико-множественное объединение операндов, т.е. из результирующей таблицы удаляются дубликаты. При выполнении операции UNION ALL образуется результирующая таблица, в которой могут содержаться строки-дубликаты.
Раздел ORDER BY
Наконец, раздел ORDER BY позволяет установить желаемый порядок просмотра результата выражения запросов. Синтаксис ORDER BY следующий:
::=
ORDER BY
[>. ]
::=
| >
[ASC | DESC]
Как видно из этих синтаксических правил, фактически задается список столбцов результата выражения запросов, и для каждого столбца указывается порядок просмотра строк результата в зависимости от значений этого столбца (ASC — по возрастанию (умолчание), DESC — по убыванию). Столбцы можно задавать их именами в том и только в том случае, когда (1) выражение запросов не содержит операций UNION или UNION ALL и (2) в списке выборки спецификации запроса этому столбцу соответствует арифметическое выражение, состоящее только из имени столбца. Во всех остальных случаях в разделе ORDER BY должен указываться порядковый номер столбца в таблице-результате выражения запросов.
15.1.2. Оператор выборки
Оператор выборки — это отдельный оператор языка SQL/89, позволяющий получить результат запроса в прикладной программе без привлечения курсора. Поэтому оператор выборки имеет синтаксис, отличающийся от синтаксиса спецификации курсора, и при его выполнении возникают ограничения на результат табличного выражения. Фактически, и то, и другое диктуется спецификой оператора выборки как одиночного оператора SQL: при его выполнении результат должен быть помещен в переменные прикладной программы. Поэтому в операторе появляется раздел INTO, содержащий список переменных прикладной программы, и возникает то ограничение, что результирующая таблица должна содержать не более одной строки. Соответственно, результат базового табличного выражения должен содержать не более одной строки, если оператор выборки не содержит спецификации DISTINCT, и таблица, полученная применением списка выборки к результату табличного выражения, не должна содержать более одной несовпадающих строк, если спецификация DISTINCT задана.
Замечание: В диалекте SQL СУБД Oracle поддерживается расширенный вариант оператора выборки, результатом которого не обязательно является таблица из одной строки. Такое расширение не поддерживается ни в SQL/89, ни в SQL/92.
15.1.3. Подзапрос
Наконец, последняя конструкция SQL/89, которая может содержать табличные выражения, — это подзапрос, т.е. запрос, который может входить в предикат условия выборки оператора SQL. В SQL/89 к подзапросам применяется то ограничение, что результирующая таблица должна содержать в точности один столбец. Поэтому в синтаксических правилах, определяющих подзапрос, вместо списка выборки указано «выражение, вычисляющее значение», т.е. арифметическое выражение. Заметим еще, что поскольку подзапрос всегда вложен в некоторый другой оператор SQL, то в качестве констант в арифметическом выражении выборки и логических выражениях разделов WHERE и HAVING можно использовать значения столбцов текущих строк таблиц, участвующих в (под)запросах более внешнего уровня. Более подробно об этом см. ниже, при описании семантики табличных выражений.
15.2. Табличное выражение
Стандарт SQL/89 рекомендует рассматривать вычисление табличного выражения как последовательное применение разделов FROM, WHERE, GROUP BY и HAVING к таблицам, заданным в списке FROM. Раздел FROM имеет следующий синтаксис:
::=
FROM
(>. ]
::=
[]
15.2.1. Раздел FROM
Результатом выполнения раздела FROM является расширенное декартово произведение таблиц, заданных списком таблиц раздела FROM. Расширенное декартово произведение (расширенное, потому что в качестве операндов и результата допускаются мультимножества) в стандарте определяется следующим образом:
«Расширенное произведение R есть мультимножество всех строк r таких, что r является конкатенацией строк из всех идентифицированных таблиц в том порядке, в котором они идентифицированы. Мощность R есть произведение мощностей идентифицированных таблиц. Порядковый номер столбца в R есть n+s, где n — порядковый номер порождающего столбца в именованной таблице T, а s — сумма степеней всех таблиц, идентифицированных до T в разделе FROM».
Как видно из синтаксиса, рядом с именем таблицы можно указывать еще одно имя «correlation name». Фактически, это некоторый синоним имени таблицы, который можно использовать в других разделах табличного выражения для ссылки на строки именно этого вхождения таблицы.
Если табличное выражение содержит только раздел FROM (это единственный обязательный раздел табличного выражения), то результат табличного выражения совпадает с результатом раздела FROM.
15.2.2. Раздел WHERE
Если в табличном выражении присутствует раздел WHERE, то следующим вычисляется он. Синтаксис раздела WHERE следующий:
::= WHERE::=
( OR
::=
( AND
::= [NOT]
::= | ()
Вычисление раздела WHERE производится по следующим правилам: Пусть R — результат вычисления раздела FROM. Тогда условие поиска применяется ко всем строкам R, и результатом раздела WHERE является таблица, состоящая из тех строк R, для которого результатом вычисления условия поиска является true. Если условие выборки включает подзапросы, то каждый подзапрос вычисляется для каждого кортежа таблицы R (в стандарте используется термин «effectively» в том смысле, что результат должен быть таким, как если бы каждый подзапрос действительно вычислялся заново для каждого кортежа R).
Заметим, что поскольку SQL/89 допускает наличие в базе данных неопределенных значений, то вычисление условия поиска производится не в булевой, а в трехзначной логике со значениями true, false и unknown (неизвестно). Для любого предиката известно, в каких ситуациях он может порождать значение unknown. Булевские операции AND, OR и NOT работают в трехзначной логике следующим образом:
true AND unknown = unknownunknown AND true = unknown
unknown AND unknown = unknown
true OR unknown = true
unknown OR true = true
unknown OR unknown = unknown
NOT unknown = unknown
Среди предикатов условия поиска в соответствии с SQL/89 могут находиться следующие предикаты: предикат сравнения, предикат between, предикат in, предикат like, предикат null, предикат с квантором и предикат exists. Сразу заметим, что во всех реализациях SQL на эффективность выполнения запроса существенно влияет наличие в условии поиска простых предикатов сравнения (предикатов, задающих сравнение столбца таблицы с константой). Наличие таких предикатов позволяет СУБД использовать индексы при выполнении запроса, т.е. избегать полного просмотра таблицы. Хотя в принципе язык SQL позволяет пользователям не заботиться о конкретном наборе предикатов в условии выборки (лишь бы они были синтаксически и семантически правильны), при реальном использовании SQL-ориентированных СУБД такие технические детали стоит иметь в виду.
Предикат сравнения
Синтаксис предиката сравнения определяется следующими правилами:
Через «<>» обозначается операция «неравенства». Арифметические выражения левой и правой частей предиката сравнения строятся по общим правилам построения арифметических выражений и могут включать в общем случае имена столбцов таблиц из раздела FROM и константы. Типы данных арифметических выражений должны быть сравнимыми (например, если тип столбца a таблицы A является типом символьных строк, то предикат «a = 5» недопустим).
Если правый операнд операции сравнения задается подзапросом, то дополнительным ограничением является то, что мощность результата подзапроса должна быть не более единицы. Если хотя бы один из операндов операции сравнения имеет неопределенное значение, или если правый операнд является подзапросом с пустым результатом, то значение предиката сравнения равно unknown.
Заметим, что значение арифметического выражения не определено, если в его вычислении участвует хотя бы одно неопределенное значение. Еще одно важное замечание из стандарта SQL/89: в контексте GROUP BY, DISTINCT и ORDER BY неопределенное значение выступает как специальный вид определенного значения, т.е. возможно, например, образование группы строк, значение указанного столбца которых является неопределенным. Для обеспечения переносимости прикладных программ нужно внимательно оценивать специфику работы с неопределенными значениями в конкретной СУБД.
Предикат between
Предикат between имеет следующий синтаксис:
::=
[NOT] BETWEEN AND
Предикат in
Предикат in определяется следующими синтаксическими правилами:
::=
[NOT] IN
| ()>
::=
>.
Типы левого операнда и значений из списка правого операнда (напомним, что результирующая таблица подзапроса должна содержать ровно один столбец) должны быть сравнимыми.
Значение предиката равно true в том и только в том случае, когда значение левого операнда совпадает хотя бы с одним значением списка правого операнда. Если список правого операнда пуст (так может быть, если правый операнд задается подзапросом), или значение «подразумеваемого» предиката сравнения x = y (где x — значение арифметического выражения левого операнда) равно false для каждого элемента y списка правого операнда, то значение предиката in равно false. В противном случае значение предиката in равно unknown. По определению значение предиката «x NOT IN S» равно значению предиката «NOT (x IN S)».
Предикат like
Предикат like имеет следующий синтаксис:
::=
[NOT] LIKE
[ESCAPE ]
::=
::=
Типы данных столбца левого операнда и образца должны быть типами символьных строк. В разделе ESCAPE должен специфицироваться одиночный символ.
Значение предиката равно true, если pattern является подстрокой заданного столбца. При этом, если раздел ESCAPE отсутствует, то при сопоставлении шаблона со строкой производится специальная интерпретация двух символов шаблона: символ подчеркивания («_») обозначает любой одиночный символ; символ процента («%») обозначает последовательность произвольных символов произвольной длины (может быть, нулевой).
Если же раздел ESCAPE присутствует и специфицирует некоторый одиночный символ x, то пары символов «x_» и «x%» представляют одиночные символы «_» и «%» соответственно.
Значение предиката like есть unknown, если значение столбца, либо шаблона не определено.
Значение предиката «x NOT LIKE y ESCAPE z» совпадает со значением «NOT x LIKE y
Предикат null
Предикат null описывается синтаксическим правилом:
::=
IS [NOT] NULL
Этот предикат всегда принимает значения true или false. При этом значение «x IS NULL» равно true тогда и только тогда, когда значение x не определено. Значение предиката «x NOT IS NULL» равно значению «NOT x IS NULL».
Предикат с квантором
Предикат с квантором имеет следующий синтаксис:
::=
::=
|
::= ALL
::= SOME | ANY
Обозначим через x результат вычисления арифметического выражения левой части предиката, а через S результат вычисления подзапроса.
Предикат «x ALL S» имеет значение true, если S пусто или значение предиката «x s» равно true для каждого s, входящего в S. Предикат «x ALL S» имеет значение false, если значение предиката «x s» равно false хотя бы для одного s, входящего в S. В остальных случаях значение предиката «x ALL S» равно unknown.
Предикат «x SOME S» имеет значение false, если S пусто или значение предиката «x s» равно false для каждого s, входящего в S. Предикат «x SOME S» имеет значение true, если значение предиката «x s» равно true хотя бы для одного s, входящего в S. В остальных случаях значение предиката «x SOME S» равно unknown.
Предикат exists
Предикат exists имеет следующий синтаксис:
::=
EXISTS
Значением этого предиката всегда является true или false, и это значение равно true тогда и только тогда, когда результат вычисления подзапроса не пуст.
15.2.3. Раздел GROUP BY
Если в табличном выражении присутствует раздел GROUP BY, то следующим выполняется он. Синтаксис раздела GROUP BY следующий:
::=
GROUP BY
[>. ]
Если обозначить через R таблицу, являющуюся результатом предыдущего раздела (FROM или WHERE), то результатом раздела GROUP BY является разбиение R на множество групп строк, состоящего из минимального числа групп таких, что для каждого столбца из списка столбцов раздела GROUP BY во всех строках каждой группы, включающей более одной строки, значения этого столбца равны. Для обозначения результата раздела GROUP BY в стандарте используется термин «сгруппированная таблица».
15.2.4. Раздел HAVING
Наконец, последним при вычислении табличного выражения используется раздел HAVING (если он присутствует). Синтаксис этого раздела следующий:
::=
HAVING
Раздел HAVING может осмысленно появиться в табличном выражении только в том случае, когда в нем присутствует раздел GROUP BY. Условие поиска этого раздела задает условие на группу строк сгруппированной таблицы. Формально раздел HAVING может присутствовать и в табличном выражении, не содержащем GROUP BY. В этом случае полагается, что результат вычисления предыдущих разделов представляет собой сгруппированную таблицу, состоящую из одной группы без выделенных столбцов группирования.
Условие поиска раздела HAVING строится по тем же синтаксическим правилам, что и условие поиска раздела WHERE, и может включать те же самые предикаты. Однако имеются специальные синтаксические ограничения по части использования в условии поиска спецификаций столбцов таблиц из раздела FROM данного табличного выражения. Эти ограничения следуют из того, что условие поиска раздела HAVING задает условие на целую группу, а не на индивидуальные строки.
Поэтому в арифметических выражениях предикатов, входящих в условие выборки раздела HAVING, прямо можно использовать только спецификации столбцов, указанных в качестве столбцов группирования в разделе GROUP BY. Остальные столбцы можно специфицировать только внутри спецификаций агрегатных функций COUNT, SUM, AVG, MIN и MAX, вычисляющих в данном случае некоторое агрегатное значение для всей группы строк. Аналогично обстоит дело с подзапросами, входящими в предикаты условия выборки раздела HAVING: если в подзапросе используется характеристика текущей группы, то она может задаваться только путем ссылки на столбцы группирования.
Результатом выполнения раздела HAVING является сгруппированная таблица, содержащая только те группы строк, для которых результат вычисления условия поиска есть true. В частности, если раздел HAVING присутствует в табличном выражении, не содержащем GROUP BY, то результатом его выполнения будет либо пустая таблица, либо результат выполнения предыдущих разделов табличного выражения, рассматриваемый как одна группа без столбцов группирования.
15.3. Агрегатные функции и результаты запросов
Агрегатные функции (в стандарте SQL/89 они называются функциями над множествами) определяются в SQL/89 следующими синтаксическими правилами:
::=
COUNT(*) |
|
::=
(DISTNICT )
::=
< AVG | MAX | MIN | SUM >([ALL] )
Как видно из этих правил, в стандарте SQL/89 определены пять стандартных агрегатных функций: COUNT — число строк или значений, MAX — максимальное значение, MIN — минимальное значение, SUM — суммарное значение и AVG — среднее значение.
15.3.1. Семантика агрегатных функций
Агрегатные функции предназначены для того, чтобы вычислять некоторое значение для заданного множества строк. Таким множеством строк может быть группа строк, если агрегатная функция применяется к сгруппированной таблице, или вся таблица. Для всех агрегатных функций, кроме COUNT(*), фактический (т.е. требуемый семантикой) порядок вычислений следующий: на основании параметров агрегатной функции из заданного множества строк производится список значений. Затем по этому списку значений производится вычисление функции. Если список оказался пустым, то значение функции COUNT для него есть 0, а значение всех остальных функций — null.
Пусть T обозначает тип значений из этого списка. Тогда результат вычисления функции COUNT — точное число с масштабом и точностью, определяемыми в реализации. Тип результата значений функций MAX и MIN совпадает с T. При вычислении функций SUM и AVG тип T не должен быть типом символьных строк, а тип результата функции — это тип точных чисел с определяемыми в реализации масштабом и точностью, если T — тип точных чисел, и тип приблизительных чисел с определяемой в реализации точностью, если T — тип приблизительных чисел.
Вычисление функции COUNT(*) производится путем подсчета числа строк в заданном множестве. Все строки считаются различными, даже если они состоят из одного столбца со значением null во всех строках.
Если агрегатная функция специфицирована с ключевым словом DISTINCT, то список значений строится из значений указанного столбца. (Подчеркнем, что в этом случае не допускается вычисление арифметических выражений!) Далее из этого списка удаляются неопределенные значения, и в нем устраняются значения-дубликаты. Затем вычисляется указанная функция.
Если агрегатная функция специфицирована без ключевого слова DISTINCT (или с ключевым словом ALL), то список значений формируется из значений арифметического выражения, вычисляемого для каждой строки заданного множества. Далее из списка удаляются неопределенные значения, и производится вычисление агрегатной функции. Обратите внимание, что в этом случае не допускается применение функции COUNT!
Замечание: оба ограничения, указанные в двух предыдущих абзацах, являются более техническими, чем принципиальными, и могут отсутствовать в конкретных реализациях. Тем не менее, это ограничения стандарта SQL/89, и их нужно придерживаться при мобильном программировании.
15.3.2. Результаты запросов
Агрегатные функции можно разумно использовать в спецификации курсора, операторе выборки и подзапросе после ключевого слова SELECT (будем называть в этом подразделе все такие конструкции списком выборки, не забывая о том, что в случае подзапроса этот список состоит только из одного элемента), и в условии выборки раздела HAVING. Стандарт допускает более экзотические использования агрегатных функций в подзапросах (агрегатная функция на группе кортежей внешнего запроса), но на практике они встречаются очень редко.
Рассмотрим различные случаи применения агрегатных функций в списке выборки в зависимости от вида табличного выражения.
Если результат табличного выражения R не является сгруппированной таблицей, то появление хотя бы одной агрегатной функции от множества строк R в списке выборки приводит к тому, что R неявно рассматривается как сгруппированная таблица, состоящая из одной (или нуля) групп с отсутствующими столбцами группирования. Поэтому в этом случае в списке выборки не допускается прямое использование спецификаций строк R: все они должны находиться внутри спецификаций агрегатных функций. Результатом запроса является таблица, состоящая не более чем из одной строки, полученной путем применения агрегатных функций к R.
Аналогично обстоит дело в том случае, когда R представляет собой сгруппированную таблицу, но табличное выражение не содержит раздела GROUP BY (и, следовательно, содержит раздел HAVING). Если в случае предыдущего абзаца было два варианта формирования списка выборки: только с прямым указанием столбцов R или только с указанием их внутри спецификаций агрегатных функций, то в данном случае возможен только второй вариант. Результат табличного выражения явно объявлен сгруппированной таблицей, состоящей из одной группы, и результат запроса можно формировать только путем применения агрегатных функций к этой группе строк. Опять результатом запроса является таблица, состоящая не более чем из одной строки, полученной путем применения агрегатных функций к R.
Наконец, рассмотрим случай, когда R представляет собой «настоящую» сгруппированную таблицу, т.е. табличное выражение содержит раздел GROUP BY и, следовательно, определен по крайней мере один столбец группирования. В этом случае правила формирования списка выборки полностью соответствуют правилам формирования условия выборки раздела HAVING: допускает прямое использование спецификации столбцов группирования, а спецификации остальных столбцов R могут появляться только внутри спецификаций агрегатных функций. Результатом запроса является таблица, число строк в которой равно числу групп в R, и каждая строка формируется на основе значений столбцов группирования и агрегатных функций для данной группы.
Какие операции не содержит язык sql
Язык допускает три типа синтаксических конструкций, начинающихся с ключевого слова SELECT: спецификация курсора (cursor specification), оператор выборки (select statement) и подзапрос (subquery). Основой всех них является синтаксическая конструкция «табличное выражение (table expression)». Семантика табличного выражения состоит в том, что на основе последовательного применения разделов from, where, group by и having из заданных в разделе from таблиц строится некоторая новая результирующая таблица, порядок следования строк которой не определен и среди строк которой могут находиться дубликаты (т.е. в общем случае таблица-результат табличного выражения является мультимножеством строк). На самом деле именно структура табличного выражения наибольшим образом характеризует структуру запросов языка SQL/89. Мы рассмотрим ниже структуру и смысл разделов табличного выражения ниже, но до этого немного подробнее обсудим три упомянутые конструкции, включающие табличные выражения.
15.1.1. Спецификация курсора
Наиболее общей является конструкция «спецификация курсора». Курсор — это понятие языка SQL, позволяющее с помощью набора специальных операторов получить построчный доступ к результату запроса к БД. К табличным выражениям, участвующим в спецификации курсора, не предъявляются какие-либо ограничения. Как видно из сводки синтаксических правил, при определении спецификации курсора используются три дополнительных конструкции: спецификация запроса, выражение запросов и раздел ORDER BY.
Спецификация запроса
В спецификации запроса задается список выборки (список арифметических выражений над значениями столбцов результата табличного выражения и констант). В результате применения списка выборки к результату табличного выражения производится построение новой таблицы, содержащей то же число строк, но вообще говоря другое число столбцов, содержащих результаты вычисления соответствующих арифметических выражений из списка выборки. Кроме того, в спецификации запроса могут содержаться ключевые слова ALL или DISTINCT. При наличии ключевого слова DISTINCT из таблицы, полученной применением списка выборки к результату табличного выражения, удаляются строки-дубликаты; при указании ALL (или просто при отсутствии DISTINCT) удаление строк-дубликатов не производится.
Выражение запросов
Выражение запросов — это выражение, строящееся по указанным синтаксическим правилам на основе спецификаций запросов. Единственной операцией, которую разрешается использовать в выражениях запросов, является операция UNION (объединение таблиц) с возможной разновидностью UNION ALL. К таблицам-операндам выражения запросов предъявляется то требование, что все они должны содержать одно и то же число столбцов, и соответствующие столбцы всех операндов должны быть одного и того же типа. Выражение запросов вычисляется слева направо с учетом скобок. При выполнении операции UNION производится обычное теоретико-множественное объединение операндов, т.е. из результирующей таблицы удаляются дубликаты. При выполнении операции UNION ALL образуется результирующая таблица, в которой могут содержаться строки-дубликаты.
Раздел ORDER BY
Наконец, раздел ORDER BY позволяет установить желаемый порядок просмотра результата выражения запросов. Синтаксис ORDER BY следующий: ::= ORDER BY [<,>. ] ::= | > [ASC | DESC]
Как видно из этих синтаксических правил, фактически задается список столбцов результата выражения запросов, и для каждого столбца указывается порядок просмотра строк результата в зависимости от значений этого столбца (ASC — по возрастанию (умолчание), DESC — по убыванию). Столбцы можно задавать их именами в том и только в том случае, когда (1) выражение запросов не содержит операций UNION или UNION ALL и (2) в списке выборки спецификации запроса этому столбцу соответствует арифметическое выражение, состоящее только из имени столбца. Во всех остальных случаях в разделе ORDER BY должен указываться порядковый номер столбца в таблице-результате выражения запросов.
15.1.2. Оператор выборки
Оператор выборки — это отдельный оператор языка SQL/89, позволяющий получить результат запроса в прикладной программе без привлечения курсора. Поэтому оператор выборки имеет синтаксис, отличающийся от синтаксиса спецификации курсора, и при его выполнении возникают ограничения на результат табличного выражения. Фактически, и то, и другое диктуется спецификой оператора выборки как одиночного оператора SQL: при его выполнении результат должен быть помещен в переменные прикладной программы. Поэтому в операторе появляется раздел INTO, содержащий список переменных прикладной программы, и возникает то ограничение, что результирующая таблица должна содержать не более одной строки. Соответственно, результат базового табличного выражения должен содержать не более одной строки, если оператор выборки не содержит спецификации DISTINCT, и таблица, полученная применением списка выборки к результату табличного выражения, не должна содержать более одной несовпадающих строк, если спецификация DISTINCT задана.
Замечание: В диалекте SQL СУБД Oracle поддерживается расширенный вариант оператора выборки, результатом которого не обязательно является таблица из одной строки. Такое расширение не поддерживается ни в SQL/89, ни в SQL/92.
15.1.3. Подзапрос
Наконец, последняя конструкция SQL/89, которая может содержать табличные выражения, — это подзапрос, т.е. запрос, который может входить в предикат условия выборки оператора SQL. В SQL/89 к подзапросам применяется то ограничение, что результирующая таблица должна содержать в точности один столбец. Поэтому в синтаксических правилах, определяющих подзапрос, вместо списка выборки указано «выражение, вычисляющее значение», т.е. арифметическое выражение. Заметим еще, что поскольку подзапрос всегда вложен в некоторый другой оператор SQL, то в качестве констант в арифметическом выражении выборки и логических выражениях разделов WHERE и HAVING можно использовать значения столбцов текущих строк таблиц, участвующих в (под)запросах более внешнего уровня. Более подробно об этом см. ниже, при описании семантики табличных выражений.
Особенности табличных выражений sql и их соответствие с концепциями реляционной модели данных Текст научной статьи по специальности «Математика»
В данной статье изложены материалы сравнения и критики SQL по поводу соответствия операторов SQL реляционной модели данных . Рассмотрены особенности табличных выражений в стандарте SQL и показаны случаи, в которых эти выражения противоречат реляционной модели. Приведены варианты использования таких табличных выражений в SQL , которые наиболее точно отражают концепции реляционной модели.
i Надоели баннеры? Вы всегда можете отключить рекламу.
Похожие темы научных работ по математике , автор научной работы — Блудов И. В.
Оператор select в языке N-Declarative Language
Решение проблемы null в запросах к реляционной базе данных, используя операторы реляционной алгебры A.
Разработка языка реляционной алгебры и реляционного исчисления и транслятора на язык SQL
Параллельная декомпозиция реляционных операций на основе распределенных колоночных индексов
ОБ ЭФФЕКТИВНОСТИ НАСЛЕДОВАНИЯ ТАБЛИЦ В СУБД PostgreSQL
i Не можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.
Текст научной работы на тему «Особенности табличных выражений sql и их соответствие с концепциями реляционной модели данных»
Особенности табличных выражений БСН-и их соответствие с концепциями реляционной модели данных
II. В. Блудов. п>ап.Ыис]оу&итаИ. сот
Аннотация. В данной статье изложены материалы сравнения и критики БС)Ь по поводу соответствия операторов БС)Ь реляционной модели данных. Рассмотрены особенности табличных выражений в стандарте БС)Ь и показаны случаи, в которых эти выражения противоречат реляционной модели. Приведены варианты использования таких табличных выражений в ЭС)Ь, которые наиболее точно отражают концепции реляционной модели.
Ключевые слова: ЭС)Ь, реляционная модель данных, БС)Ь запросы, табличные выражения
Общеизвестно, что 8С)Ь является стандартным языком реляционных баз данных, но этот факт не делает его реляционным. В действительности, он отдалился от реляционной модели достаточно давно. Следует понимать различия 8С)Ь и реляционной теории, чтобы избежать возможных проблем, связанных с этими различиями.
Данная статья посвящена исследованию различий 8()Ь и реляционной модели данных. Более конкретно, в ней рассматривается один из важных разделов 8С)Ь — табличные выражения. В статье проводится анализ табличных выражений стандарта 8()Ь. их особенностей и сравнение с операторами реляционной модели данных. На основе этого анализа выясняется, как такие выражения следует использовать, чтобы они соответствовали реляционной модели. С целью написания качественного 8()Ь следует применять соответствующие практики, что позволит ощутить преимущества реляционной модели.
2. Определения кортежа и отношения
Пусть Т1,Т2. Тп (п>0) — определённые типы, не обязательно различные. Пусть . !/ — отличные имена атрибутов, ассоциированные с каждым 77. Каждая из п комбинаций «имя атрибута/тип» называется атрибутом. С каждым атрибутом ассоциировано значение атрибута vi типа 77; каждая из п пар атрибут/значение называется компонентом. Множество из всех п таких компонент определяют значение кортежа (кортеж, для краткости) над атрибутами А1,А2. Ап. Множество из всех п атрибутов называется заголовком кортежа.
Пусть будет заголовком кортежей, и пусть tl, t2, tm будут различные кортежи заголовка . Сочетание и множества кортежей называется значением отношения (отношением, для краткости), над атрибутами Al, А2, . Ап, где Al, А2, . Ап все атрибуты . Заголовком отношения будет , телом отношения будет множество кортежей .
Выводы из определения:
• В реляционной модели каждый атрибут каждого отношения должен иметь имя (то есть анонимные атрибуты запрещены), и такие имена должны быть уникальны в данном отношении (то есть запрещены дублирующиеся имена атрибутов). В SQL данные правила уместны не везде: они верны для значений переменных таблиц, определённых с помощью CREATE TABLE и CREATE VIEW, но не для результатов запросов над такими таблицами.
• Отношения никогда не содержат кортежей-дубликатов. Эго свойство следует из того, что тело отношения определено как множество кортежей, а множество в математике не содержит дублирующихся элементов. Поведение SQL в данном смысле не верно: поскольку таблицы в SQL могут содержать дублирующиеся строки, отсюда они не являются отношениями в общем смысле.
• Кортежи в отношении не упорядочены сверху вниз. Эго свойство следует опять из того, что тело отношения определено как множество, а в математическом множестве элементы не упорядочены. Конечно, из того факта, что кортежи в отношениях не упорядочены, не следует то, что запросы не могут включать спецификации ORDER BY. Однако это означает, что результат такого запроса не будет отношением. Отсортированные результаты удобны для отображения, однако, такой запрос не является реляционный оператором.
• Атрибуты в отношении также не упорядочены слева направо, потому что заголовок отношения — также математическое множество. Поведение SQL в данном контексте неверно: в SQL таблицах колонки упорядочены слева направо.
• Кортежи никогда не содержат NULL — поскольку, по определению, для каждого атрибута кортежи содержат значения соответствующего типа.
• Отношение не содержат NULL — поскольку тело отношения является множеством кортежей, а кортежи не содержат NULL.
3. Замкнутость реляционной модели. Правила выведения типов отношений и таблиц.
По определению результатом каждого реляционного оператора должно быть отношение. И напротив, любой оператор, результатом которого не является отношение по определению не может быть реляционным оператором. В случае SQL реляционные операторы не могут возвращать результаты, содержащие строки дубликаты, упорядоченные столбцы, NULL, неименованные столбцы, дублирующиеся имена столбцов. Замкнутость реляционной модели крайне важна, оно позволяет нам писать в реляционной модели вложенные выражения. Не используйте любые операторы, нарушающие замыкания, если Вы хотите использовать результат в дальнейших реляционных выражениях.
Реляционная модель использует специальные правила выведения типов отношений, которые предполагают, что, если нам известен заголовок входных отношений в операции, мы можем вывести заголовок выходного отношения этой операции. Преимущество такого метода в избегании сложностей, зависящих от порядкового номера атрибутов.
SQL же поддерживает выведение типов несколько не корректно. Во-первых, в SQL вообще нет понятия реляционных типов, взамен он оперирует типами строк. Во-вторых, он допускает в результирующих таблицах неименованные столбцы. В-третьих, допускает в результирующих таблицах дублирование имен столбцов. Для использования SQL реляционным образом Вам следует применять некоторые правила, как это делают реляционные операторы. Это предполагает надлежащее именование атрибутов отношений:
• Для всех атрибутов, представляющих «одну и ту же информацию», по возможности назначать одинаковые имена. И напротив, если два атрибута представляют разную информацию, правильно будет определить для них различные имена. Единственный случай, когда следовать данным рекомендациям невозможно, — если два атрибута одной таблицы предоставляют одинаковую информацию.
• Для каждой базовой таблицы определите представления во избежание возможного переименования атрибутов в будущем.
• Используйте такие представления вместо лежащих в их основе базовых таблиц.
• Используйте спецификацию AS для определения подходящих имен для любых столбцов, которые не имеют имени, или имя их не уникально.
Мы не можем игнорировать факт, что столбцы в SQL остаются упорядоченными даже если нам этого не нужно. Следующий код предполагает упорядоченность атрибутов:
• JOIN, UNION, INTERSECT и EXCEPT—в особенности если не определена спецификация CORRESPONDING в последних трех случаях.
• В перечислении имен атрибутов, следующем за определением переменной области значений
• В перечислении имен атрибутов, определённых в CREATE VIEW
• INSERT, если не определён список имен атрибутов.
• ALL и ANY сравнения, если размерность операндов больше одного
• В выражениях VALUES
4. Сравнение типов в SQL
Рассмотрим общеизвестный факт, что в реляционной модели два значения могут быть сравнены, только если они одного и того же типа. Основная идея здесь в том, что СУБД должна запрещать выполнять любые реляционные операторы (join, union, что угодно), которые подразумевают явное/неявное сравнение значений различных типов. Было бы полезно, если при попытке пользователя сравнить значения различных типов, СУБД запретит данное сравнение, сообщив об ошибке, и попросит пользователя исправить ошибку перед выполнением. Ни один из известных сегодня SQL продуктов не ведет себя подобным образом. В сегодняшних продуктах в зависимости от того, как Вы настроите базу данных, выполнение запроса прервется или же вернет не верный ответ (точнее не совсем не верный ответ, а правильный ответ на неправильный вопрос).
В SQL же реализована строгая типизация, но в несколько слабой форме. Так сравнение строк и чисел не допустимо, однако сравнение целых и действительных чисел допустимо, поскольку перед выполнением сравнения целое число будет приведено к вещественному типу. Такое приведение типов широко распространено, однако, в контексте SQL его применение к реляционным операциям, таким, как объединение, пересечение и разность, приводит к весьма странным результатам, которые впоследствии содержат строки, не принадлежащие ни одному из операндов. Рассмотрим объединение таблиц T1 и Т2 .
SELECT X , Y FROM T1 UNION
SELECT X , Y FROM T2
0,0 0,0 0,0 1.0 1.0 2.0 0,0 2.0
Таким образом, результат содержит строки не принадлежащие ни таблице Т1, ни таблице Т2 — весьма странное объединение.
Рекомендация: избегайте приведения типов, где это возможно. Так, в контексте SQL, следует быть уверенным, что колонки с одинаковым именем имеют одинаковый тип. Если избежать этого не удается — используйте явное приведение типов, используя CAST или его эквиваленты.
5. Табличные выражения. Особенности стандарта SQL в сравнении с реляционной моделью
В данной главе мы рассмотрим крайне важное табличное выражение, которое возникает в многочисленных контекстах языка SQL. В большинстве случаях, в действительности, его можно рассматривать как вершину синтаксического дерева. Следует отметить, что стандарт ссылается на эту конструкцию как на выражения запроса (query expression) и приписывает другое (более ограниченное) понятие для табличного выражения (“table expression”). Мы предпочитаем термин табличное выражение, поскольку он более точно отражает, что выражение возвращает таблицу (точнее неименованную таблицу). Напротив, стандарт предполагает “table expression” просто как частный случай, что мы называем select выражением без SELECT раздела как такового.
5.1 Соединения / JOIN EXPRESSIONS
В общем случае табличные выражение разделены на join и non-join табличные выражения
Рассмотрим только первый из двух случаев. В общем случае Join выражение представляет явное соединение двух таблиц, представленных как ссылка на
таблицу (table reference). Более точно, Join выражение это либо cross join, либо явно/неявно подразумевает наличие типа соединения (join type).
table-reference CROSS JOIN table-primary | table-reference [join-type ] JOIN table-primary
[ ON search-condition | USING (column-name-list) ]
| table-reference NATURAL [ join-type ] JOIN table-primary | table-reference UNION JOIN table-primary
“Cross join” — это другое название того, что более точно называть расширенное декартовое произведение (сокращенно просто декартово произведение в контексте SQL). Пусть А и В будут таблицы, представленные как результат вычислений table reference. Тогда результатом выражение “A CROSS JOIN В» будет таблица, содержащая все возможные строки R, которые являются конкатенацией строк из А и В. Из этого следует, что соединение A CROSS JOIN В семантически эквивалентно следующему select-выражению:
( SELECT А.*, В * FROM А, В )
Из определения видно, что общие атрибуты таблиц А и В встречаются в результате дважды.
Другие Join выражения
Синтаксис для других join выражений следующий: table-reference [join-type ] JOIN table-primary
[ ON search-condition | USING (column-name-list) ]
| table-reference NATURAL [ join-type ] JOIN table-primary
| table-reference UNION JOIN table-primary
Тип соединения (Join type) в свою очередь может быть одним из следующих: join-type ::=
Следует отметить что:
1. NATURAL и UNION не могут быть одновременно указаны.
2. Если указано NATURAL или UNION — тогда ни ON условие, ни USING условие не могут быть указаны.
3. Если не указано ни NATURAL, ни UNION — тогда либо ON условие, либо USING условие должны быть указаны.
4. Если тип соединение опущен — тогда INNER тип предполагается по умолчанию
5. Слово OUTER в случаях LEFT, RIGHT, и FULL является необязательным и не оказывает никакого эффекта на общий смысл выражений.
Рассмотрим следующие варианты соединения:
1. table-reference JOIN table-primary ON search-condition
2. table-reference JOIN table-primary USING (column-name-list)
3. table-reference NATURAL JOIN table-primary
Пусть А и В будут таблицы, представленные как результат вычисления table
1. “A JOIN В ON cond,» (где cond — условное выражение) по определению семантически эквивалентно следующему select выражению:
FROM А, В WHERE cond)
Из определения видно, что общие атрибуты таблиц А и В встречаются в результате дважды.
2. Пусть список атрибутов в условии USING будет определён как Cl, С2 Сп, и каждый атрибут С 1, С2, . Сп должен одновременно быть атрибутом А и В. Тогда соединение семантически эквивалентно Случаю 1, в котором ON условие представлено как — ON А.С1 = В.Cl AND А.С2 = В.С2 AND . AND A.Cn = B.Cn. За исключением того, что общие атрибуты Cl, С2 Сп встречаются в результате только один раз, а не дважды. А атрибуты в результирующей таблицы упорядочены следующим образом: сперва идут общие атрибуты (упорядоченные слева на право, как это указано в условии USING); затем остальные атрибуты А
(в порядке каком они указаны в А); затем остальные атрибуты В (в
порядке каком они указаны в В).
3. Выражение семантически эквивалентно Случаю 2, в котором список
атрибутов включает все общие атрибуты А и В. Отметим, что если таких
общих атрибутов нет, в таком случае выражение A NATURAL JOIN В
сводиться к A CROSS JOIN В.
Рассмотрим следующие примеры:
S JOIN SP ON S.SNO = SP.SNO S JOIN SP USING ( SNO ) S NATURAL JOIN SP
Эти три выражения эквивалентны: хотя первое возвращает таблицу, содержащую два одинаковых столбца SNO, второе и третье содержит только один такой столбец.
Отметим, что, хотя результатом вычислений этих выражений является таблица, содержащая множество строк, эти выражения не могут быть использованы как самостоятельный оператор. Необходимо определить cursor над этими выражениям и получать строки одну за другой с помощью такого курсора.
i Не можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
1. Использование NATURAL JOIN для обозначения соединения более предпочтительно, чем остальные методы — такая формулировка будет наиболее краткой. Однако следует убедиться, что одноимённые столбцы имеют одинаковый тип.
2. Старайтесь избегать использования JOIN ON, поскольку он гарантировано возвращает результат с дублируемыми именами столбцов. Однако, если вам действительно необходимо выполнить некоторый вид экви-соединения, самостоятельно выполните надлежащее именование столбцов над полученным результатом.
3. В использования JOIN USING убедитесь, что столбцы с одинаковым именем имеют одинаковый тип.
4. В случае использования CROSS JOIN убедитесь, что отсутствуют общие имена столбцов.
Замечание по внешнему соединению
Внешние соединения LEFT, RIGHT, FULL and UNION были специально разработаны, чтобы вставлять NULL в таблицы результат, поэтому их
следует рассматривать в контексте влияния NULL на SQL модель данных. Они будут опущены в текущем контексте. Говоря реляционным языком, это некоторый вид принуждения — оно позволяет выполнить объединение таблиц, даже если типы операндов не удовлетворяют требованиям объединения. Внешнее соединение заполняет недостающие столбцы обоих операндов NULL-ами перед выполнением объединения, и таким образом операнды станут удовлетворять требованиям объединения. Но никто не мешает заполнять недостающие столбцы подходящими значениями взамен NULL.
5.2 Ссылки на таблицу/ TABLE REFERENCES
Ссылка на таблицу (table reference) может ссылаться на некоторую таблицу, не важно именованная это таблица (например, базовая таблица или представление) или неименованная. Ссылки на таблицу используется в SQL для двух целей: они определяют операнды в разделе FROM select выражений и операнды в join выражениях. Что касается синтаксиса, то ссылка на таблицу состоит либо из join выражения (рассмотреные выше), либо из имени таблицы
(а), либо из табличного выражения в скобках (Ь). В Случае (а) ссылка на таблицу может выключать необязательную конструкцию AS, целью которой является объявление переменной области значений (range variable) для таблицы в запросе, а также указывать имена столбцов для этой таблицы. В Случае (Ь) ссылка на таблицу должна включать в себя такую AS конструкцию.
| table [ [ AS ] range-variable [ ( column-commalist) ]
| ( query-expression-body) [ AS ] range-variable [ (
Список column-commalist, если он определен, должен явно указывать имя для каждого атрибута в соответствующей таблице и не может определять одно имя дважды.
Стоит отметить, что стандарт SQL не использует термин “переменные области значений”. Вместо этого он использует термин “correlation name”, но не определяет тип объектов, к которым можно обращаться, используя данное имя. “Переменные области значений” (range variable) — это общепринятый термин. SQL всегда требует, чтобы sdect-выражение (также как и join-выражения) формулировались в терминах переменных области значений. Если такие переменные не объявлены явно, тогда SQL предполагает наличие
неявных переменных области значений с тем же именем, что и соответствующие таблицы. Нет ничего плохого в том, чтобы объявлять такие перемены области значений там, где они не требуются явным образом, особенно в сложных выражениях они помогут сделать выражение более понятным. Однако будьте внимательны, поскольку правила области видимости имен в SQL сложны в понимании.
Исследуя вопросы выведения типов в SQL, стоит рассмотреть пример: SELECT Р.* , S.SNO , S.SNAME , S.STATUS FROM Р, S
WHERE P.CITY = S. CITY
AND P.PNAME > S.SNAME
Выражение P.PNAME > S.SNAME весьма необычно, поскольку выражение предполагает применение к результату выражения FROM, и естественно, переменные отношения Р и S не являются частью этого результата. В действительности, сложно объяснить как нечто P.PNAME может появиться в выражениях WHERE и SELECT, поскольку всё должно быть описано исключительно в терминах результата выражения FROM. Стандарт SQL разъясняет это, но способом гораздо более сложным, чем описан в реляционной модели.
Область видимости переменных области значений — то есть контекст, в котором на них можно ссылаться и имя этой переменой должно быть уникальным, определён следующим образом:
• Если ссылка на таблицу присутствует в FROM выражении, тогда областью видимости переменной является sdect-выражение его включающее (разделы SELECT, FROM, WHERE, GROUP BY, HAVING — которые образует данное sdect-выражение). Исключая любые вложенные select-выражения или join-выражения, в которых другие переменные области значений могут быть объявлены с тем же именем.
• Если ссылка на таблицу присутствует в join-выражении, тогда областью видимости является это join-выражение. Исключая любые вложенные sdect-выражения или join-выражения, в которых другие переменные области значений могут быть объявлены с тем же именем.
Описанные замечания по поводу области видимости переменных не описывают все возможные случаи. В случае join-выражений вопрос видимости переменных области значений весьма сложный. Например, если join-выражение, содержащее ссылку на таблицу, присутствует в свою очередь
в разделе FROM — тогда область видимости таблицы расширяется до select-выражения, включающей данный раздел FROM:
SELECT DISTINCT SP.PNO, S.CITY
FROM SP NATURAL JOIN S
Причина вероятно в том, что область видимости в данном случае должна быть такой же, как если бы join выражение заменили бы двумя операндами join, разделёнными запятой.
Однако одно очень нелогичное следствие из этих правил видимости показано в следующем примере.
SELECT DISTINCT SP *
FROM SP NATURAL JOIN S
Результат выражения будет включать столбцы PNO и QTY, но не столбец SNO — потому что в результат join-выражение не содержит столбец SP.SNO (в действительности, использование SP.SNO в SELECT выражении должно было быть синтаксической ошибкой). Вместо этого результат join выражения содержит столбец SNO без всякого уточнения, что является результатом своего рода объединения столбцов S.SNO и SP.SNO.
5.3 Объединение, разность и пересечение
SQL операторы UNION, EXCEPT и INTERSECT основаны на хорошо известных операторах теории множеств: объединение, разность и
пересечение. Две таблицы, которые являются операндами объединения, разности и пересечения, должны иметь одинаковую степень (то есть одинаковое количество столбцов), соответствующие столбцы должны иметь совместимые типы данных.
UNION и EXCEPT присутствуют в “nonjoin query expressions”, а INTERSECT присутствует в “nonjoin query terms”.
| query-expression-body < UNION | EXCEPT >[ ALL | DISTINCT ]
[ CORRESPONDING [ BY ( column-commalist) ] ] query-term nonj oin-query-term
| query-term INTERSECT [ ALL | DISTINCT]
[ CORRESPONDING [ BY ( column-commalist) ] ] query-primary Пересечение / INTERSECT
Пусть таблицы А и В будут результатом вычислений table-term и table-primary. Возможны следующие варианты пересечений:
1. A INTERSECT [ ALL | DISTINCT] CORRESPONDING BY ( column-commalist) В
2. A INTERSECT [ ALL | DISTINCT] CORRESPONDING В
3. A INTERSECT [ ALL | DISTINCT] В
Если не указано спецификатор ALL или DISTINCT, тогда DISTINCT предполагается по умолчанию.
Рассмотрим три случая, которые не содержат опцию ALL.
1. Пусть СУ, С2 . Сп список атрибутов в BY выражении. Каждый атрибут из С1, С2 . Сп одновременно определяет атрибуты^ и В. Данный случай по определению семантический эквивалентен следующему выражению:
(( SELECT Cl, С2, .. ., Сп FROM А)
( SELECT Cl, С2, . Сп FROM В ))
Другими словами, пусть АС будет таблица, полученая из А удалением всех столбцов, которые не отмечены в BY выражении; и таблица ВС получена из В аналогичным образом. Тогда результатом пересечения будет таблица из п столбцов, строка R присутствует в результате тогда и только тогда, когда она присутствует ив АС, ив ВС. Результат выражения не содержит строки дубликаты.
2. Пересечение по определению семантически эквивалентно пересечению в Случае 1, в котором список атрибутов включает в себя все атрибуты, общие для А и В.
3. В данном случае пересечение выполняется не согласно сравнению значений атрибутов с одинаковым именем, как в Случае 1 и 2, а сравниваются в соответствии порядковой позицией данных атрибутов. То есть, i-ый атрибут из А сравнивается с i-ым атрибут из В (для всех / от 1 до п, где п — степень п; напоминаем, что Ап В должны иметь одинаковую степень). Результат также будет степени п, и некая строка присутствует в результате тогда и только тогда, когда она одновременно присутствует ив А, ив В. Опять же результат выражения не будет содержать дубликаты.
Если определена опция ALL в указанных трех случаях, то результат будет идентичным, за исключением того, что результат будет содержать строки дубликаты. Точнее, предположим, что строка R содержится т раз в первом операнде и п раз во втором операнде (т > 0 , п > 0) — тогда строка R будет присутствовать в результате р раз, где р меньшее из т и п.
Для операции объединения множество возможных случаев аналогично операции пересечения:
1. A UNION [ ALL | DISTINCT] CORRESPONDING BY ( column-commalist) В
2. A UNION [ ALL | DISTINCT] CORRESPONDING В
ЗА UNION [ALL | DISTINCT] В
Эти случаи определены аналогично случаям пересечения, учитывая, что для операции UNION некая строка содержится в результирующей таблице тогда и только тогда, когда она содержится как минимум в одной из таблиц операнда. По умолчанию, результат не содержит строки дубликата. В случае, если указана опция ALL, и предполагая, что строка R содержится т раз в первом операнде и п раз во втором операнде (т > 0 , п > 0) — тогда строка R будет присутствовать в результате р раз, где р = т + п.
Множество возможных случаев аналогично случаям пересечения:
1. A EXCEPT [ ALL | DISTINCT] CORRESPONDING BY ( column-commalist) В
2. A EXCEPT [ ALL | DISTINCT] CORRESPONDING В
3. A EXCEPT [ ALL | DISTINCT] В
И снова эти случаи определены аналогично случаям пересечения, учитывая, что для операции EXCEPT некая строка содержится в результирующей таблице тогда и только тогда, когда она содержится в первой таблице операнде и не содержится во второй таблице операнде. По умолчанию результат не содержит строки дубликаты. В случае если указана опция ALL, и предполагая, что строка R содержится т раз в первом операнде и п раз во втором операнде (т > 0 , п > 0) — тогда строка R будет присутствовать в результате р раз, где р больше из т — пи 0.
• Убедитесь, что соответствующие столбцы имеют одинаковые имена и типы.
• Всегда определяйте COREESPONDING, где это возможно. Поскольку не все SQL продукты могут поддерживать ее, в таком случае, вам придется самостоятельно позаботиться об упорядочивание столбцов.
• Не используйте опцию BY в спецификации CORRESPONDING
• Никогда не определяйте опцию ALL, и более того, желательно использовать опцию DISTINCT явно. Зачастую пользователи указывают ALL в случаях, если знают об отсутствии дубликатов во входных таблицах, и указывают системе не тратить время, удаляя их.
Замечание по поводу синтаксиса
Дополнительно следует отметить некоторое несоответствие синтаксиса NATURAL JOIN и UNION (INTERSECT и EXCEPT). Предположим, что А и В именованные таблицы, типы которых удовлетворяют требованиям UNION, тогда следующие выражения имеют верный или не верный синтаксис:
A NATURAL JOIN B — верно
A UNION B — не верно
TABLE A UNION TABLE B — верно
TABLE A NATURAL JOIN TABLE B — не верно
SELECT * FROM A UNION SELECT * FROM B — верно
SELECT * FROM A NATURAL JOIN SELECT * FROM B — не верно
(TABLE A) UNION (TABLE B) — верно
(TABLE A) NATURAL JOIN (TABLE B) — не верно
(TABLE A) AS AA NATURAL JOIN (TABLE B) AS BB — верно
5.4 Простая таблица / Simple table
Как было описано ранее, простой запрос (query primary) используется для обозначения второго операнда операции пересечения.
i Не можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
Ранее мы уже рассмотрели соединения (joined table) и пересечения, объединения и разность (nonjoin query expressions). Сейчас мы остановимся на рассмотрении выражения “TABLE table” и конструкторы таблиц (table-value-constructor). Select выражения (query-specification) будут рассмотрены позже.
• Выражение “TABLE table” (где table — именованная таблица: базовая таблица или представление) по определению семантически эквивалентно выражению:
( SELECT * FROM table)
• Конструктор таблиц представляет собой список конструкторов строк:
где каждый конструктор строки определяет в точности одну строку, а конструктор таблицы определяет таблицу, которая является своего рода “UNION ALL” таких строк.
Конструктор строк в свою очередь может иметь следующую форму:
[ ROW ](row-value-constructor-element-conmalist) | ( query-expression )
Другими словами, конструктор строк представляет собой или список компонентов строки в скобках, или табличное выражение в скобках:
1. Компонентом строки может быть скалярное выражение или одно из ключевых слов: DEFAULT или NULL. (DEFAULT и NULL допустимы, только если конструктор строки используется в INSERT выражении)
2. Табличное выражение в скобках должно вычисляться как таблица, содержащая в точности одну строку. В этом случае значением конструктора строки будет полученная строка. Стандарт SQL определяет такое выражение как строчное выражение (row subquery). Возникнет ошибка времени выполнения, если данное строчное выражение вернет таблицу, содержащую более одной строки. Однако, если данное строчное выражение вернет таблицу, не содержащую ни одной строки, тогда значением конструктора строки будет строка полностью состоящая из NULL.
• Поскольку столбцы таблицы упорядочены слева направо, и в конструкторе не поддерживается определение значения атрибута по его имени, вам необходимо убедиться, что все строки имеет соответствующий тип — то есть на i-ой позиции строки должно находиться значение i-oro атрибута таблицы.
• Убедитесь, что не описали одну строку дважды.
Пусть Т будет именованная таблица, имена и типы атрибутов совпадают с таблицей поставщиков S. Тогда следует отметить, что следующие два INSERT выражения отличаются по смыслу:
1. INSERT INTO Т VALUES ( SELECT * FROM S WHERE SNO = ‘S6’)
2. INSERT INTO T ( SELECT * FROM S WHERE SNO = ‘S6’)
Предполагая, что выражение SNO = ’S61 ложно, тогда первое выражение вставляет в таблицу Т строку, полностью состоящую из NULL; в то время как второе выражение не вставляет ни одной строки.
5.5 SELECT выражение
В качестве sdect-выражения может быть рассмотрено табличное выражение, которое не содержит никаких JOIN, UNION, EXCEPT или INTERSECT. Хотя такие операторы могут использоваться в качестве вложенных.
: := SELECT [ ALL | DISTINCT ] select-list FROM table-reference-commalist
[ GROUP BY [ALL | DISTINCT] column-commalist ]
SELECT [ ALL | DISTINCT ] select-list
1. Если не указан спецификатор ALL или DISTINCT, ALL предполагается по умолчанию.
2. Мы предполагаем, что результатом вычисления разделов FROM, WHERE, GROUP BY и HAVING (не важно, какие из них присутствуют в запросе, а какие нет) будет таблица 77. ( В действительности 77- неименованная таблица).
3. Пусть Т2 будет таблица, полученная из 77 вычислением списка select-list.
4. Если указано ключевое слово DISTINCT, тогда ТЗ будет таблица, полученная из Т2 удалением строк дубликатов. Если DISTINCT не указано, тогда таблица ТЗ будет равна Т2.
5. ТЗ будет результат вычисления данного select-выражения.
Рассмотрим список элементов select-list. Возможны два случая, причем второй случай — всего лишь сокращённая форма первого случая.
1. Элемент select-list имеет вид:
scalar-expression [ [ AS ] column ]
Скалярное выражение обычно включает один или более атрибутов таблицы Т1. Для каждой строки таблицы Т1 вычисляется данное скалярное выражение. Список результатов вычисления таких скалярных выражений по строке таблицы Т1 является строка таблицы Т2. Раздел AS, если он присутствует, определяет имя столбца в результирующий таблице Е2 для заданного скалярного выражения. Само ключевое слово AS является необязательным.
2. Элемент select-list имеет вид:
• Если имя переменной области значений опущено (то есть, элемент select-list представлен ‘*’), тогда этот select-item должен быть единственным в разделе SELECT. Такая форма является сокращением для списка всех атрибутов таблицы Т1, в порядке слева направо.
• Если элемент select-list содержит имя переменной области значений, тогда select-item представляет список всех атрибутов указанной переменной в порядке слева направо. Как мы помним, в качестве переменной области значений не явно может быть использовано имя таблицы.
• Если данный элемент select-list используется при определении представлений или ограничений, тогда список атрибутов вычисляется в момент определения данных ограничений или представлений.
Следовательно, если впоследствии в соответствующие таблицы будут добавлены новые атрибуты, то это не повлияет на данные представления или ограничения.
• Всегда указывайте опцию DISTINCT, чтобы позаботиться об удалении строк дубликатов.
Предположим, список ссылок на таблицу представлен в виде таблиц А, В , С. Тогда результатом вычисления раздела FROM будет таблица, которая является декартовым произведением таблиц А, В , С. Декартовое произведение от одной таблицы Т по определению равно Т.
Пусть Т будет таблица, полученая после вычисления раздела FROM. Тогда результатом раздела WHERE будет таблица, полученная из Т удалением всех строк, для которых условное выражение (search-condition) не равно true. Если раздел WHERE опущен, результатом будет таблица Т.
Раздел GROUP BY
GROUP BY [ALL | DISTINCT] column-commalist
Пусть T будет результат вычисления разделов FROM и WHERE. Каждый атрибут в списке column-commalist в разделе GROUP BY должен быть атрибутом таблицы Т. Результатом раздела GROUP BY будет сгруппированная таблица, то есть множество из групп строк, полученное из Т, где строки в группе имеют одинаковое значение для атрибутов, указанных в разделе GROUP BY. Если не указан спецификатор ALL или DISTINCT, ALL предполагается по умолчанию. Если указано ключевое слово DISTINCT, тогда группы строк не будут содержать дубликатов. Такие группы сортированы внутри множества по количеству строк в группе от большего к меньшему. Отметим, что результат GROUP BY не является правильной таблицей, поэтому раздел GROPU BY никогда не используется без соответствующего
раздела SELECT, задача которого получить правильную таблицу из промежуточного результата.
Если select выражение включает в себя раздел GROUP BY, то дополнительное ограничение накладывается на раздел SELECT. Каждый элемент списка SELECT должен иметь общее значение для группы. Предполагается, что такие элементы не должен включать в себя никакие ссылки на атрибуты из таблицы Т, которые не являются общими для группы, если только такие ссылки не являются аргументом (или частью выражения аргумента) для функции агрегации (функции над множеством), которая вычисляет единственное скалярное значение для коллекции скалярных значений.
Пусть G будет сгруппированная таблица, полученная после вычисления FROM, WHERE и GROUP BY разделов. Если раздел GROUP BY опущен, тогда G представляет собой сгруппированную таблицу, полученную после вычисления разделов FROM и WHERE, которая содержит только одну группу. Таким образом, полагается, что объявлен неявный раздел GROUP BY, который не содержит ни одного атрибута. Результатом раздела HAVING будет сгруппированная таблица, полученная из G удалением всех групп, для которых условное выражение (search-condition) не равно true. Скалярное выражение в разделе HAVING должно оперировать общими значениями для группы (как скалярные выражения в разделе SELECT, если присутствует раздел GROUP BY). Если раздел HAVING опущен, а раздел GROUP BY присутствует — тогда результатом будет таблица G. Если оба раздела HAVING и GROUP BY опущены — тогда результатом будет правильная (несгруппированная) таблица Т, полученная вычислением разделов FROM и WHERE.
Замечание по поводу избыточности
Следует отметить, что разделы GROUP BY и HAVING являются в действительности избыточными. Имеется ввиду, что для каждого select-выражения, включающего данные разделы, существует эквивалентное по смыслу выражение, которое не будет включать эти разделы.
В данной статье рассмотрено поведение табличных выражений стандарта SQL в сравнении с реляционными операторами. В реляционной модели понятие отношений гарантирует что: отсутствуют строки дубликаты, отсутствуют дублирующиеся столбцы, отсутствуют неименованные столбцы, отсутствует
упорядоченность столбцов, отсутствует упорядоченность строк, отсутствуют неопределённые значения (NULL). В статье были показаны случаи, в которых операторы SQL ведут себя отличным от реляционной модели образом, то есть возвращают таблицы, которые не являются отношениями. Также были описаны практики, которые позволяют вам избежать таких случаев и использовать SQL исключительно реляционным образом.
Использование SQL реляционным образом возможно в большинстве случаев. Однако, поскольку существующие реализации далеки от идеальных, временами вы обнаружите, что это приводит к потери производительности. Если в таких случаях вы склонитесь к не «истинно реляционному» использованию, тогда следует понимать, что вы идете на такие компромиссы с позиций концептуальной целостности. Всегда следует понимать правильную в теории ситуацию, и вы должны иметь веские основания уклониться от неё. Вам также следует описать эти причины, для того чтобы отказаться от них в будущем (к примеру, если новая версия продукта, который вы используете, лучше решает интересующую вас задачу), тогда вы сможете вернуться к оригинальным идеям.
7. Список литературы
[1] C.J. Date. Hugh Darwen. A gude to the SQL standard. 4th edition. Addison-Wesley. (1997).
[2] C.J. Date. SQL and Relational Theory: How to Write Accurate SQL Code. O’Reilly Media, Inc. (2009).
[3] C. J. Date. Database in Depth: Relational Theory for Practitioners. Sebastopol, Calif.: O’Reilly Media, Inc. (2005).
[4] C. J. Date, Hugh Darwen. “Foundation for Future Database Systems: The Third Manifesto”, Addison-Wesley Pub Co; 2nd edition (2000).
[5] Имеется перевод: Дейт К., Дарвен X. Основы будущих систем баз данных. Третий манифест. 2-е изд. (под ред. С. Д. Кузнецова). М.: Янус-К, 2004.
[6] К. Дж. Дейт. Введение в системы баз данных. Изд. 8-е./ Перев. с англ. -М.: Вильямс, 2005.
[7] С.Д. Кузнецов. Базы данных: языки и модели. — М.: ООО «Бином-Пресс», 2008 .
Введение в базы данных. Обзор основных возможностей SQL и СУБД PostgreSQL
Курс «Введение в базы данных. Обзор основных возможностей SQL и СУБД PostgreSQL» направлен на изучение языка SQL на примере СУБД PostgreSQL.
Практическая часть курса направлена на наглядное иллюстрирование структуры и основных команд языка, написания запросов различного уровня сложности, перевод бизнес-задач на язык SQL. Курс содержит большое количество задач и практических примеров, подлежащих как самостоятельному решению, так и демонстрируемых преподавателем.
- О курсе
- Формат
- Информационные ресурсы
- Требования
- Программа курса
- Результаты обучения
- Формируемые компетенции
- Направления подготовки
О курсе
Курс состоит из разделов, в которых освещаются на практике базовые понятия и операции языка SQL. Полученные знания могут являться не только основой для более глубокого погружения в материал, но и минимальным набором знаний для получения первой IT-профессии. Курс освещает основные конструкции языка, учит создать\изменять таблицы и получать из них данные.
Материал разделов покрывает следующие темы:
— Основы языка SQL, клиенты для работы с базами данных.
— Особенности работы в PostgreSQL.
— Основные типы данных SQL, полезные операторы и функции.
— Выборки, фильтрации, агрегации, группировки и сортировки данных средствами SQL.
— Создание и удаление таблиц в базе данных.
— Работа с объединением таблиц в SQL.
— Подзапросы и временные таблицы.
Все темы подкрепляются реальными практическими примерами и заданиями для самостоятельного закрепления материала.
Формат
Обучение в онлайн формате.
видеолекции продолжительностью до 15 минут
анимационные ролики с инфографикой
материалы для самостоятельного изучения
тесты в конце разделов для закрепления знаний
Информационные ресурсы
1. PostgreSQL. Основы языка SQL: учеб. пособие / Е. П. Моргунов; под ред. Е. В. Рогова, П. В. Лузанова. — СПб.: БХВ-Петербург, 2018. — 336 с
2. Астахова, И. Ф. СУБД : язык SQL в примерах и задачах / Астахова И. Ф. , Мельников В. М. , Толстобров А. П. , Фертиков В. В. — Москва : ФИЗМАТЛИТ, 2009. — 168 с
Требования
Для полноценного освоения учебного материала по дисциплине студент должен:
— Иметь уровень владения компьютером — достаточный для самостоятельной установки и удаления программ.
Программа курса
Раздел 1. Введение в базы данных, основные понятия языка SQL
1.1. Введение в базы данных, язык SQL
1.2. Начало работы с PostgreSQL
1.3. Основные термины и понятия для работы с БД
1.4. Типы данных (практическая часть)
1.5. Схема базы данных
Раздел 2. Особенности проектирование схемы данных
2.1. Ограничения: первичные и внешние ключи (практическая часть)
2.2. Связи и отношения между таблицами (практическая часть)
2.3. Нормальные формы
2.4. Индексы
2.5. NULL значения (практическая часть)
Раздел 3. Основные операторы запросов
3.1. Оператор CREATE TABLE (практическая часть)
3.2. Оператор ALTER (практическая часть)
3.3. Операторы INSERT, UPDATE (практическая часть)
3.4. Оператор SELECT (практическая часть)
3.5. Операторы DROP, DELETE, TRUNCATE (практическая часть)
Раздел 4. Выборка данных
4.1. Таблицы истинности
4.2. Операторы фильтрации: часть 1 (практическая часть)
4.3. Операторы фильтрации: часть 2 (практическая часть)
4.4. Группировка (практическая часть)
4.5. Агрегирующие функции (практическая часть)
4.6. Вспомогательные функции (практическая часть)
Раздел 5. Связи между таблицами
5.1. Внутреннее соединение (практическая часть)
5.2. Внешние соединения: right, left (практическая часть)
5.3. Внешние соединения: full, cross (практическая часть)
5.4. Объединение данных (практическая часть)
5.5. Типовые задачи применения соединений (практическая часть)
Раздел 6. Перевод бизнес-задачи в SQL
6.1. Разбираем требования (практическая часть)
6.2. Уточнения и краевые условия (практическая часть)
6.3. Проектирование сущностей (практическая часть)
6.4. CRUD операции (практическая часть)
Результаты обучения
В ходе освоения курса обучаемый будет знать\уметь:
— Писать простые запросы для получения/вставки/изменения/удаления данных.
— Преобразовывать бизнес-задачу к языку SQL.
— Основные типы данных SQL, полезные операторы и функции.
— Строить запросы с объединением таблиц, фильтрацией, агрегацией.
— Строить подзапросы и временные таблицы, понимать их область применения.
В ходе освоения курса обучаемый будет владеть:
— навыками решения конкретных задач по работе с SQL;
Формируемые компетенции
ОПК-2: Способен разрабатывать оригинальные алгоритмы и программные средства, в том числе с использованием современных интеллектуальных технологий, для решения профессиональных задач
ОПК-4: Способен применять на практике новые научные принципы и методы исследований
УК-1: Способен демонстрировать глубокое знание и понимание фундаментальных наук, а также знания в междисциплинарных областях профессиональной деятельности
ОПК-2: Способен разрабатывать оригинальные алгоритмы и программные средства, в том числе с использованием современных интеллектуальных технологий, для решения профессиональных задач
ПК-3: Способен на деятельность, направленную на решение задач аналитического характера, предполагающих выбор и многообразие актуальных способов решения задач
УК-3: Способен: — проектировать и разрабатывать продукцию, процессы и системы в условиях неопределенности и альтернативных решений в рамках междисциплинарных областей; — выбрать и применять передовые методы и технологии проектирования или использовать творческий подход для разработки новых и оригинальных методов проектирования и разработки
Направления подготовки
- Русский язык курса
- 6 недель длительность курса
- от 5 до 6 часов в неделю понадобится для освоения
- 3 зачётных единицы для зачета в своем вузе
