Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
УМП-БД.doc
Скачиваний:
17
Добавлен:
05.12.2018
Размер:
1.26 Mб
Скачать

26. Язык запросов sql

В конце 80-х годов произошел стремительный взлет популярности СУБД одного конкретного типасистемы управления реляционными базами данных. С тех пор реляционная база данных (РБД) стала единственным стандартным типом базы данных. Данные в РБД хранятся в простой табличной форме, что дает реляционным базам данных много преимуществ по сравнению с базами данных более ранних разработок. SQL представляет собой язык именно реляционных баз данных

Краткая история SQL

История SQL тесно связана с развитием реляционных баз данных. Понятие реляционной базы данных было введено доктором Э. Ф. Коддом, научным сотрудником компании IBM. В июне 1970 года доктор Кодд опубликовал статью под названием "Реляционная модель для больших банков совместно используемых данных'' (“A Relational Model of Data for Large Shared Data Banks"), в которой в общих чертах была изложена математическая теория хранения данных в табличной форме и их обработки. Реляционные базы данных и SQL ведут свое начало от этой статьи, появившейся в журнале " Communications of the Association for Computing Mashinery”.

  1. 1 Основы sql

Операторы

В SQL используется приблизительно тридцать операторов. Каждый оператор "просит" СУБД выполнить определенное действие, например, прочитать данные, создать таблицу или добавить в таблицу новые данные. Все операторы SQL имеют одинаковую структуру.

Оператор

Описание

Обработка данных

SELECT

Считывает данные из БД

INSERT

Добавляет новые строки в БД

DELETE

Удаляет строки из БД

UPDATE

Обновляет данные, существующие в БД

Определение данных

CREATE TABLE

Создает в БД новую таблицу

DROP TABLE*

Удаляет таблицу из БД

ALTER TABLE*

Изменяет структуру существующей таблицы

CREATE VIEW

Добавляет в БД новое представление

DROP VIEW*

Удаляет представление из БД

CREATE INDEX*

Создает индекс для столбца

DROP INDEX

Удаляет индекс столбца

CREATE SYNONYM*

Определяет синоним для имени таблицы

DROP SYNONYM*

Удаляет синоним для имени таблицы

COMMENT*

Определяет заметки для таблицы или столбца

LABEL*

Определяет заголовок таблицы или столбца

Управление доступам

GRANT

Предоставляет пользователю право доступа

REVOKE

Отменяет право доступа

Управление транзакциями

COMMIT

Завершает текущую Транзакцию

ROLLBACK -

Отменяет текущую транзакцию

Программный SQL

DECLARE

Определяет курсор для запроса

EXPLAIN*

Описывает план доступа к данным для запроса

OPEN

Открывает курсор для чтения результатов запроса

FETCH

Считывает строку из результатов запроса

CLOSE

Закрывает курсор

PREPARE*

Подготавливает оператор SQL к динамическому выполнению

EXECUTET

Динамически выполняет оператор SQL

DESCRIBE*

Описывает подготовленный запрос

* He являются частью стандарта ANSI/ISO, но часто встречаются в наиболее распространенных СУБД

Каждый оператор SQL начинается с глагола, т.е. ключевого слова, описывающего действие, выполняемое оператором. Типичными глаголами являются create (создать), insert (добавить), delete (удалить) и commit (завершить). После глагола идет одно или несколько предложений. Предложение описывает данные, с которыми работает оператор, или содержит уточняющую информацию о действии, выполняемом оператором. Каждое предложение также начинается с ключевого слова, такого как where (где), from (откуда), into (куда) и having (имеющий). Одни предложения в операторе являются обязательным, а другие — нет. Конкретная структура и содержимое предложения могут изменяться. Многие предложения содержат имена таблиц или столбцов; некоторые из них могут содержать дополнительные ключевые слова, константы и выражения.

В стандарте ANSI/ISO определены ключевые слова, которые применяются в качестве глаголов и в предложениях операторов. В соответствии со стандартом, эти ключевые слова нельзя использовать для именования объектов базы данных, таких как таблицы, столбцы и пользователи. Во многих реализациях SQL этот запрет ослаблен, однако следует избегать использования ключевых слов в качестве имен таблиц и столбцов. В табл. 5.2 перечислены ключевые слова, входящие в стандарт SQLL Стандарт SQL2 расширяет этот список до 300 ключевых слов.

ADA

CURRENT

GO-

OF

SOME

ALL

CURSOR

GOTO

ON

SQL

AND

DEC

GRANT

OPEN

SQLCODE

ANY

DECIMAL

GROUP

OPTION

SQLERROR

AS

DECLARE

HAVING

OR

SUM

ASC

DEFAULT

IN

ORDER

TABLE

AUTHORIZATION

DELETE

INDICATOR

PASCAL

TO

AVG

DESC

INSERT

PLI

UNION

BEGIN

DISTINCT

INT

PRECISION

UNIQUE

BETWEEN

DOUBLE

INTEGER

PRIMARY

UPDATE

BY

END

INTO

PRIVILEGES

USER

С

ESCAPE

IS

PROCEDURE

VALUES

CHAR

3SXEC

KEY

PUBLIC

VIEW

CHARACTER

EXISTS

LANGUAGE

REAL

WHENEVER

CH&CK

FETCH

LIKE

REFERENCES

WHERE

CLOSE

FLOAT

MAX

ROLLBACK

WITH

COBOL

FOR

MIN

SCHEMA

WORK

COMMIT

FOREIGN

MODULE

SECTION

CONTINUE

FORTRAN

NOT

SELECT

COUNT

FOUND

NULL

SET.

CREATE

FROM

NUMERIC

SMALLINT

Почти во всех реализациях SQL ключевые слова можно писать как прописными, так и строчными буквами. На практике быстрее набирать весь оператор строчными буквами.

Имена

У каждого объекта в базе данных есть уникальное имя. Имена используются в операторах SQL и указывают, над каким объектом базы данных оператор должен выполнить действие. В стандарте ANSI/ISO определено, что имена имеются у таблиц, столбцов и пользователей. Во многих реализациях SQL поддерживаются также дополнительные именованные объекты, такие как хранимые процедуры, именованные отношения "первичный ключ — внешний ключ" и формы для ввода данных.

В соответствии со стандартом ANSI/ISO,в SQL имена должны содержать от 1 до 18 символов, начинаться с буквы и не содержать пробелы или специальные символы пунктуации. В стандарте SQL2 максимальное число символов в имени увеличено до 128. На практике, однако, в различных СУБД разрешено использование в именах таблиц специальных символов, которые в различных базах данных могут быть разными. Поэтому для повышения переносимости лучше делать имена сравнительно короткими и избегать использования в них специальных символов.

Имена таблиц

Если в операторе указано имя таблицы, SQL предполагает, что происходит обращение к одной из ваших собственных таблиц (т.е. таблиц, которые создали вы). Имея соответствующее разрешение, можно обращаться к таблицам, владельцами которых являются другие пользователи, с помощью полного имени таблицы. Полное имя состоит из имени владельца таблицы и собственно ее имени, разделенных точкой. Например, полное имя таблицы birthdays, владельцем которой является пользователь по имени sam, имеет следующий вид:

SAM.BIRTHDAYS

Полное имя таблицы можно использовать вместо простого имени таблицы во всех операторах SQL.

Имена столбцов

Если в операторе задается имя столбца, SQL сам определяет, в какой из указанных в этом же операторе таблиц содержится данный столбец. Однако если в оператор требуется включить два столбца из различных таблиц, но с одинаковыми именами, необходимо указать полные имена столбцов, которые однозначно определяют их местонахождение. Полное имя столбца состоит из имени таблицы, содержащей столбец, и имени столбца {простого имени}, разделенных точкой (.). Например, полное имя столбца sales из таблицы salesreps имеет следующий вид:

SALESREPS.SALES

Если столбец находится в таблице, владельцем которой является другой пользователь, то в полном имени столбца следует использовать полное имя таблицы. Например, полное имя столбца birth_date в таблице birthdays, владельцем которой является пользователь sam, имеет следующий вид:

SAM . BIRTHDAYS . BIRTH_DATE.

Полное имя столбца можно использовать вместо простого имени во всех операторах SQL; об исключениях, говорится при описании конкретных операторов.

Типы данных

В стандарте ANSI/ISO определены типы данных, которые можно использовать для представления информации в реляционной базе данных. Типы данных, имеющиеся в стандарте SQL1, составляют лишь минимальный набор и поддерживаются во всех коммерческих СУБД. В табл. 5.3 перечислены типы данных, определенные в стандартах SQL1 и SQL2.

Тип данных

Описание

CHAR(длина)

Строки символов постоянной длины

CHARACTER(длина)

VARCHAR(длина)

Строки символов переменной длины*

CHAR VARYING(длина)

CHARACTER VARYING(длина)

NCHAR(длина)

Строки локализованных символов постоянной длины*

NATIONAL CHAR(длина)

NATIONAL CHARACTER(длина)

NCHAR VARYING(длина)

Строки локализованных символов переменной длины*

NATIONAL CHAR VARYING(длина)

NATIONAL CHARACTER VARYING(длина)

INTEGER

Целые числа

INT

SMALLINT

Маленькие целые числа

BIT (длина)

Строки битов постоянной длины*

BIT VARYING^HHO^

Строки битов переменной длины*

NUMERIC(точность, степень)

Масштабируемые целые (десятичные) числа

DECIMAL(точность, степень)

DEC(точность, степень)

FLOAT (точность)

Числа с плавающей запятой

REAL

Числа с плавающей запятой низкой точности

DOUBLE PRECISION

Числа с плавающей запятой высокой точности

DATE

Календарная дата*

TIME (точность)

Время

TIMESTAMP(точность)

Дата и время*

INTERVAL

Временной интервал*

Типы данных, появившиеся в SQL2

В SQL1 используются следующие типы данных:

Строки символов постоянной длины. В столбцах, имеющих этот тип данных, обычно хранятся имена людей и компаний, адреса, описания и т.д.

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

Масштабируемые целые числа. В столбцах данного типа хранятся числа, имеющие дробную часть, которые необходимо вычислять точно, например, курсы валют и проценты. Кроме того, в таких столбцах часто хранятся денежные величины.

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

Дополнительные типы данных

В большинстве коммерческих СУБД помимо типов данных, определенных в стандарте SQL1, имеется множество дополнительных типов данных, большинство из которых вошло в стандарт SQL2.

Строки символов переменной длины. Почти во всех СУБД поддерживается тип данных varchar, позволяющий хранить строки символов, длина которых изменяется в некотором диапазоне. В стандарте SQL1 были определены строки постоянной длины, которые справа дополняются пробелами.

Денежные величины. Во многих СУБД поддерживается тип данных money или currency, который обычно хранится в виде десятичного числа или числа с плавающей запятой. Наличие отдельного типа данных для представления денежных величин позволяет правильно форматировать их при выводе на экран.

Дата и время. Поддержка значений даты/времени также широко распространена в различных СУБД, хотя способы ее реализации довольно сильно отличаются друг от друга. Как правило, над значениями этого тепа данных можно выполнять различные операции. В стандарт SQL2 входит определение типов данных date, time, timestamp и interval, включая поддержку часовых поясов и возможность указания точности представления времени (например, десятые или сотые доли секунды).

Булевы данные. Некоторые СУБД явным образом поддерживают логические значения (true ИЛИ FALSE).

Простые запросы на чтение

Язык SQL предназначен в первую очередь для выполнения запросов. Оператор select, который используется для построения SQL-запросов, является наиболее мощным из всех операторов SQL. Несмотря на богатство возможностей этого оператора, его изучение можно начать с создания простых запросов, а затем постепенно увеличивать их сложность.

Оператор SELECT

Оператор select читает данные из базы данных и возвращает их в виде таблицы результатов запроса.

• В предложении select указывается список столбцов, которые должны быть возвращены оператором select. Возвращаемые столбцы могут содержать значения, считываемые из столбцов таблиц базы данных, или значения, вычисляемые во время выполнения запроса.

• В предложении from указывается список таблиц, которые содержат элементы данных, считываемые запросом.

• Предложение where показывает, что в результаты запроса следует включать только некоторые строки. Для отбора строк, включаемых в результаты запроса, используется условие поиска.

• Предложение group by позволяет создать итоговый запрос. Обычный запрос включает в результаты запроса по одной строке для каждой строки из базы данных. Итоговый запрос, напротив, вначале группирует строки базы данных по определенному признаку, а затем включает в результаты запроса одну итоговую строку для каждой группы.

• Предложение having показывает, что в результаты запроса следует включать только некоторые из групп, созданных с помощью предложения group by, В этом предложении, как и в предложении where, для отбора включаемых групп используется условие поиска.

• Предложение order by сортирует результаты запроса да оснований данных, содержащихся в одном или нескольких столбцах. Если это предложение не указано, результаты запроса не будут отсортированы.

Предложение SELECT

В предложении select, с которого начинаются все операторы select, необходимо указать элементы данных, которые будут возвращены в результате запроса. Эти элементы задаются в виде списка возвращаемых столбцов, разделенных запятыми. Для каждого элемента из этого списка в таблице результатов запроса будет создан один столбец. Столбцы в таблице результатов будут расположены в том же порядке, что и элементы списка возвращаемых столбцов. Возвращаемый столбец может представлять собой:

имя столбца, идентифицирующее один из столбцов, содержащихся в таблицах, которые перечислены в предложении from. Когда в качестве возвращаемого столбца указывается имя столбца таблицы базы данных, SQL просто берет значение этого столбца для каждой из строк таблицы и помещает его в соответствующую строку таблицы результатов запроса;

константа, показывающая, что в каждой строке результатов запроса должно содержаться одно и то же значение;

выражение, показывающее что SQL должен вычислять значение, помещаемое в результаты запроса, по формуле, определенной в выражении.

Предложение from

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

Результаты запроса на чтение

Результатом SQL-запроса. на чтение всегда является таблица, содержащая данные и ничем не отличающаяся от таблиц базы данных. Если пользователь набирает оператор SQL в интерактивном режиме, СУБД выводит результаты запроса на экран в табличной форме. Если программа посылает запрос СУБД с помощью программного SQL, то СУБД в6звращает таблицу результатов запроса программе. В любом случае результаты запроса всегда имеют такой же формат, как и обычные таблицы, содержащиеся в базе данных. Как правило, результаты запроса представляют собой таблицу с несколькими сроками и столбцами.

В некоторых случаях результатом запроса может быть единственное значение

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

И, наконец, запрос может вернуть результаты, содержащие ноль строк

Даже в таком случае результаты запроса считаются таблицей. Таблица, приведенная выше, содержит два столбца и ноль строк.

Обратите внимание, что поддержка отсутствующих данных в SQL распространяется и на результаты запроса. Если один из элементов данных в базе данных имеет значение null, то оно попадет в результаты запроса при считывании этого элемента. Например, в таблице salesreps значение null содержится в столбцах quota и manager. менеджеров.

To, что SQL-запрос всегда возвращает таблицу данных, очень важно. Это означает, что результаты запроса можно записать обратно в базу данных в виде таблицы. Это означает также, что результаты двух запросов, имеющие похожую структуру, можно объединить в одну таблицу. И, наконец, это говорит о том, что результаты запроса сами могут стать предметом дальнейших запросов. Таким образом, табличная структура реляционной базы данных тесно связана с реляционными запросами SQL. Таблицам можно посылать запросы, а запросы возвращают таблицы.

Наиболее простые запросы извлекают данные из столбцов, расположенных в одной таблице базы данных. Оператор select для простых запросов состоит только из двух обязательных предложений. В предложении select перечисляются имена требуемых столбцов; в предложении from указывается таблица, содержащая эти столбцы.

На логическом уровне запрос выполняется путем построчного просмотра таблицы, указанной в предложении from. Для каждой строки таблицы берутся значения столбцов, входящих в список возвращаемых столбцов, и создается одна строка результатов запроса. Таким образом, таблица результатов простого запроса на чтение содержит одну строку данных для каждой строки исходной таблицы базы данных.

Вычисляемые столбцы

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

Во многих СУБД реализованы дополнительные арифметические операции, операции над строками символов и встроенные функции, которые можно применять в выражениях SQL. Их также можно использовать в выражениях в списке возвращаемых столбцов, как в следующем примере для DB2:

Кроме того, в списке возвращаемых столбцов можно использовать константы SQL. Это может пригодиться для создания результатов запроса, которые более удобны для восприятия, как в следующем примере:

Чтение всех столбцов (оператор SELECT *)

Иногда требуется получить содержимое всех столбцов таблицы. На практике такая ситуация может возникнуть, когда вы впервые сталкиваетесь с новой базой данных и необходимо быстро получить представление о ее структуре и хранимых в ней данных. С учетом этого в SQL разрешается использовать вместо списка возвращаемых столбцов символ звездочки (*), который означает, что требуется прочитать все столбцы:

В стандарте ANSI/ISO сказано, что в предложении select можно использовать либо символ чтения всех столбцов, либо список возвращаемых столбцов, но не оба одновременно. Однако во многих реализациях SQL символ звездочки (*) считается просто одним из возвращаемых столбцов. Таким образом, запрос

SELECT *, (SALES - TARGET) FROM OFFICES

допустим в большинстве коммерческих диалектов SQL (в частности, в DB2, Oracle и SQL Server), однако не разрешен стандартом ANSI/ISO.

Символ чтения всех столбцов очень удобно использовать в интерактивном SQL. Однако следует избегать использования его в программном SQL, поскольку изменения в структуре базы данных могут привести к краху приложения. Предположим, например, что таблица offices была удалена из базы данных, а затем создана вновь, при этом был изменен порядок столбцов и добавлен новый, седьмой столбец. Если программа ожидает, что запрос select * from offices возвратит результат, содержащий шесть столбцов определенных типов, она почти наверняка перестанет работать после изменения порядка столбцов и добавления нового столбца.

Этих сложностей можно избежать, если в программах запрашивать требуемые столбцы по именам. Например, следующий запрос возвращает те же результаты, что и select * from offices. Он не восприимчив к изменениям структуры базы данных, пока в таблице offices существуют столбцы с указанными именами.

SELECT OFFICE, CITY, REGION, MGR, TARGET, SALES FROM OFFICES

Повторяющиеся строки (ключевое слово DISTINCT)

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

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

Если ключевое слово distinct не указано, повторяющиеся строки не удаляются. Можно также указать ключевое слово all, явно показывая, что повторяющиеся строки следует оставить, однако делать это не обязательно, поскольку ключевое слово all используется по умолчанию.

Отбор строк (предложение WHERE)

SQL-запросы, считывающие из таблицы все строки, полезны при просмотре базы данных и создании отчетов, однако редко применяются для чего-нибудь еще. Обычно требуется выбрать из таблицы несколько строк и включить в результаты запроса только их. Чтобы указать, какие строки требуется отобрать, следует использовать предложение where. Ниже показано несколько запросов, в которых используется это предложение.

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

• Если условие поиска имеет значение true, строка будет включена в результаты запроса.

• Если условие поиска имеет значение false, то строка исключается из результатов запроса.

• Если условие поиска имеет значение null, то строка исключается из результатов запроса.

Условие поиска служит фильтром для строк таблицы. Строки, удовлетворяющие условию поиска, проходят через фильтр и становятся частью результатов запроса. Строки, не удовлетворяющие условию поиска, отфильтровываются и исключаются из результатов запроса.

В SQL используется множество условий поиска, позволяющих эффективно и естественным образом создавать различные типы запросов. Ниже рассматриваются пять основных условий поиска (в стандарте ANSI/ISO они называются предикатами).

Сравнение. Значение одного выражения сравнивается со значением другого выражения. Например, такое условие поиска используется для выбора всех офисов, находящихся в восточном регионе, или всех служащих, фактические объемы продаж которых превышают плановые.

Проверка на принадлежность диапазону значений. Проверяется, попадает ли указанное значение в определенный диапазон значений. Например, такое условие поиска используется для нахождения служащих, фактические объемы продаж которых превышают $100000, но меньше $500000.

Проверка на членство в множестве. Проверяется, совпадает ли значение выражения с одним из значений из заданного множества. Например, такое условие поиска используется для выбора офисов, расположенных в Нью-Йорке, Чикаго или Лос-Анджелесе.

Проверка на соответствие шаблону. Проверяется, соответствует ли строковое значение, содержащееся в столбце, определенному шаблону. Например, такое условие поиска используется для выбора клиентов, имена которых начинаются с буквы "Е".

Проверка на равенство значению NULL. Проверяется, содержится ли в столбце значение null. Например, такое условие поиска используется для нахождения всех служащих, которым еще не был назначен менеджер.

СРАВНЕНИЕ (=, О, <, <=, >, >=)

Наиболее распространенным условием поиска в SQL является сравнение. При сравнении SQL вычисляет и сравнивает значения двух выражений для каждой строки данных. Выражения могут быть как очень простыми, например, содержать одно имя столбца или константу, так и более сложными — арифметическими — выражениями. В SQL имеется шесть различных способов сравнения двух выражений. Когда SQL сравнивает значения двух выражений, могут получиться три результата:

  • если сравнение истинно, результат проверки имеет значение TRUE;

  • если сравнение ложно, результат проверки имеет значение FALSE;

  • если хотя бы одно из двух выражений имеет значение NULL, то результатом проверки будет значение NULL.

Использование значений NULL в запросах может привести к некоторым неожиданным результатам.

ПРОВЕРКА НА ПРИНАДЛЕЖНОСТЬ ДИАПАЗОНУ ЗНАЧЕНИЙ (BETWEEN)

Задается предложением BETWEEN нижняя_граница AND верхняя_граница

При проверке на принадлежность диапазону верхний и нижний пределы считаются частью диапазона.

Инвертированная версия проверки на принадлежность диапазону позволяет выбрать значения, лежащие за пределами диапазона.

ПРОВЕРКА НА ЧЛЕНСТВО В МНОЖЕСТВЕ (IN)

Еще одним условием поиска является проверка на членство в множестве (IN). В этом случае проверяется, соответствует ли значение данных какому-либо значению из заданного списка.

С помощью формы not in можно убедиться в том, что значение данных не является членом заданного множества. Проверяемое выражение в проверке in может быть любым допустимым выражением, однако обычно оно представляет собой короткое имя столбца, как в предыдущих примерах. Если результатом проверяемого выражения является значение null, то проверка IN также возвращает значение null. Все значения в списке заданных значений должны иметь один и тот же тип данных, который должен быть сравним с типом данных проверяемого выражения.

Как и проверка between, проверка in не добавляет в возможности SQL ничего нового, поскольку условие поиска

Х IN (А, В, С)

полностью эквивалентно условиям

(X = A) OR (X = В) OR (X = С)

Однако проверка in предлагает гораздо более эффективный способ выражения условия поиска, особенно если множество содержит большое число элементов. В стандарте ANSI/ISO не определено максимальное количество элементов множества, и в большинстве коммерческих реализаций не задано явного верхнего предела. По соображениям переносимости лучше избегать множеств, содержащих один элемент, наподобие такого:

CITY IN ('New York')

Их следует заменять на следующее простое сравнение:

CITY = 'New York'

Проверка на соответствие шаблону (LIKE)

Для чтения строк, в которых содержимое некоторого текстового столбца совпадает с заданным текстом, можно использовать простое сравнение/

Поверка на соответствие шаблону (ключевое слово like) позволяет определить, соответствует ли значение данных в столбце некоторому шаблону. Шаблон представляет собой строку, в которую может входить один или более подстановочных знаков. Эти знаки интерпретируются особым образом.

ПОДСТАНОВОЧНЫЕ ЗНАКИ

Подстановочный знак % совпадает с любой последовательностью из нуля или более символов.

Подстановочный знак "_" (символ подчеркивания) совпадает с любым отдельным символом.

Подстановочные знаки можно помещать в любое место строки шаблона, и в одной строке может содержаться несколько подстановочных знаков.

С помощью формы not like можно находить строки, которые не соответствуют шаблону. Проверку like можно применять только к столбцам, имеющим строковый тип данных. Если в столбце содержится значение null, то результатом проверки like будет значение null.

СИМВОЛЫ ПРОПУСКА *

При проверке строк на соответствие шаблону может оказаться, что подстановочные знаки входят в строку символов в качестве литералов. Например, нельзя проверить, содержится ли знак процента в строке, просто включив его в шаблон, поскольку SQL будет считать этот знак подстановочным. Как правило, это не вызывает серьезных проблем, поскольку подстановочные знаки довольно редко встречаются в именах, названиях товаров и других текстовых данных, которые обычно хранятся в базе данных.

В стандарте ANSI/ISO определен способ проверки наличия в строке литералов, использующихся в качестве подстановочных знаков. Для этого применяются символы пропуска. Когда в шаблоне встречается такой символ, то символ, следующий непосредственно за ним, считается не подстановочным знаком, а литералом. (Происходит пропуск символа.) Непосредственно за символом пропуска может следовать либо один из двух подстановочных знаков, либо сам символ пропуска, поскольку он тоже приобретает в шаблоне особое значение.

Символ пропуска определяется в виде строки, состоящей из одного символа, и предложения escape

Первый символ процента в шаблоне, следующий за символом пропуска, считается литералом; второй считается подстановочным знаком.

Символы пропуска часто используются при проверке на соответствие шаблону; именно поэтому они были включены в стандарт ANSI/ISO. Однако они не входили в первые реализации SQL и поэтому не очень распространены. Для обеспечения переносимости приложений предложения escape использовать не следует.

ПРОВЕРКА НА РАВЕНСТВО ЗНАЧЕНИЮ NULL (IS NULL)

Значения null обеспечивают возможность применения трехзначной логики в условиях поиска. Для любой заданной строки результат применения условия поиска может быть true, false или null (в случае, когда водном из столбцов содержится значение null). Иногда бывает необходимо явно проверять значения столбцов на равенство null и непосредственно обрабатывать их. Для этого в SQL имеется специальная проверка на равенство значению null (is null).

Инвертированная форма проверки на null (is not null) позволяет отыскать строки, которые не содержат значения null:

В отличие от условий поиска, описанных выше, проверка на null не может возвратить значение null в качестве результата. Она всегда возвращает true или FALSE.

Может показаться странным, что нельзя проверить значение на равенство null с помощью операции сравнения, например:

Ключевое слово null здесь нельзя использовать, поскольку на самом деле это не настоящее значение; это просто сигнал о том, что значение неизвестно. Даже если бы сравнение было возможно, правила обработки значений null в сравнениях привели бы к тому, что оно вело бы себя не так, как ожидается. Когда SQL встречает строку, в которой столбец rep_office содержит значение null, выполняется следующая проверка:

NULL = NULL

Что будет результатом этого сравнения: true или false? Так как значения по обе стороны знака равенства неизвестны, то, в соответствии с правилами логики SQL, условие поиска должно вернуть значение null. Поскольку условие поиска возвращает результат, отличный от true, строка исключается из таблицы результатов запроса — это совсем не то, к чему вы стремились! Из-за правил обработки значений null в SQL необходимо использовать проверку is null.

СОСТАВНЫЕ УСЛОВИЯ ПОИСКА (AND, OR И NOT)

Простые условия поиска, описанные в предыдущих параграфах, после применения к некоторой стуже возвращают значения true, false или null. С помощью правил логики эти простые условия можно объединять в более сложные. Обратите внимание на то, что условия поиска, объединенные с помощью ключевых слов and, or и not, сами могут быть составными.

Ключевое слово or используется для объединения двух условий поиска, из которых как минимум одно должно быть истинным:

Для объединения двух условий поиска, оба из которых должны быть истинными, можно также использовать ключевое слово and:

И, наконец, можно использовать ключевое слово not, чтобы выбрать строки, в которых условие поиска ложно:

СОРТИРОВКА РЕЗУЛЬТАТОВ ЗАПРОСА (ПРЕДЛОЖЕНИЕ ORDER BY)

Строки результатов запроса, как и строки таблицы базы данных, не имеют определенного порядка. Включив в оператор select предложение order by, можно отсортировать результаты запроса. Это предложение состоит из ключевых слов order by, за которыми следует список имен или порядковых номеров столбцов, разделенных запятыми. Первый столбец является главным ключом сортировки; столбцы, следующие за ним, являются все более второстепенными ключами. Можно сортировать результаты запроса по любому элементу списка возвращаемых столбцов запроса.

В предложении order by можно выбрать возрастающий или убывающий порядок сортировки. По умолчанию, данные сортируются в порядке возрастания. Чтобы сортировать их по убыванию, следует включить в предложение сортировки ключевое слово desc.

Чтобы определить порядок сортировки по возрастанию, необходимо использовать ключевое слово asc, однако из-за того, что такой порядок принят по умолчанию, это ключевое слово обычно не указывают.

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

Стандарт SQL2 позволяет управлять порядком сортировки отдельно по каждому ключу. Это может оказаться важным при работе с локализованными наборами символов или для обеспечения переносимости между системами с таблицами кодировок ASCII и EBCDIC. Однако эта часть спецификации SQL2 является довольно сложной, и в большинстве реализации SQL либо вообще игнорируются вопросы последовательности сортировки, либо используются собственные схемы управления этой последовательностью.

ПРАВИЛА ВЫПОЛНЕНИЯ ОДНОТАБЛИЧНЫХ ЗАПРОСОВ

Результаты запроса, возвращенные оператором select, получаются в результате поочередного применения входящих в оператор предложений. Вначале применяется предложение from (оно выбирает таблицу, содержащую требуемые данные). Затем применяется предложение where (которое по определенному критерию отбирает из таблицы строки). Далее применяется предложение select (которое создает указанные столбцы результатов запроса и при необходимости удаляет повторяющиеся строки), и, наконец, для сортировки результатов запроса применяется предложение order by.

ОБЪЕДИНЕНИЕ РЕЗУЛЬТАТОВ НЕСКОЛЬКИХ ЗАПРОСОВ (UNION)*

Иногда появляется необходимость объединения результатов двух или более запросов в одну таблицу. SQL поддерживает такую возможность с помощью оператора Union.

Оператор uNion создает одну таблицу результатов запроса, в которой содержатся строки результатов как первого, так и второго запросов. В запросах оператор union используется следующим образом:

Чтобы таблицы результатов запроса можно было объединить с помощью оператора union, они должны соответствовать следующим требованиям:

• две таблицы должны содержать одинаковое число столбцов;

• тип данных каждого столбца первой таблицы должен совпадать с типом данных соответствующего столбца во второй таблице;

• ни одна из двух таблиц не может быть отсортирована с помощью предложения order by, однако объединенные результаты запроса можно отсортировать.

Имена столбцов в двух запросах, объединенных с помощью оператора union, не обязательно должны быть одинаковыми. Поскольку столбцы в двух таблицах могут иметь различные имена, столбцы результатов запроса, возвращенные оператором union, имен не имеют. Стандарт ANSI/ISO накладывает дополнительные ограничения на операторы select, участвующие в операторе union. Он разрешает использовать в списке возвращаемых столбцов только имена столбцов или указатель на все столбцы (select *) и запрещает использовать выражения. В большинстве коммерческих реализации SQL, тем не менее, это ограничение ослаблено, и в списке возвращаемых столбцов разрешено использовать простые выражения. Однако во многих реализациях SQL не разрешается включать в операторы select предложения group by или having, а в некоторых не разрешается использовать в списке возвращаемых столбцов агрегатные функции (т.е. нельзя использовать итоговые запросы).

ЗАПРОС НА ОБЪЕДИНЕНИЕ И ПОВТОРЯЮЩИЕСЯ СТРОКИ *

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

Если в результатах оператора union необходимо сохранить повторяющиеся строки, сразу за ключевым словом union следует указать ключевое слово all. Эта форма запроса вернет результаты с повторяющимися строками:

Обработка повторяющихся строк для операторов union и select осуществляется по разному. Оператор select по умолчанию оставляет повторяющиеся строки (select all). Чтобы удалить повторяющиеся строки, необходимо явно указать ключевое слово distinct. Оператор union по умолчанию удаляет повторяющиеся строки. Чтобы оставить повторяющиеся строки, необходимо явно указать ключевое слово ALL.

Специалисты по работе с базами данных критиковали обработку повторяющихся строк в SQL и указывали на эту "непоследовательность" языка как на одну из проблем. Причина такой "непоследовательности" заключается в том, что в SQL в качестве установок по умолчанию выбираются наиболее часто используемые варианты:

• на практике большинство простых операторов select не возвращают повторяющиеся строки, поэтому по умолчанию принято не удалять их;

• на практике большинство операторов union возвращают повторяющиеся строки, что нежелательно, поэтому по умолчанию такие строки удаляются.

Удаление повторяющихся строк из таблицы результатов запроса занимает много времени, особенно если результаты запроса содержат большое количество строк. Если известно, что оператор union не возвратит повторяющиеся строки, необходимо явно указать ключевое слово all, тогда запрос будет выполняться быстрее.

ЗАПРОС НА ОБЪЕДИНЕНИЕ И СОРТИРОВКА *

Предложение order by нельзя использовать ни в одном из операторов select, объединенных оператором union. Нет смысла выполнять сортировку результатов таких запросов, поскольку пользователь все равно не увидит их в чистом виде. Однако объединенные результаты запросов, возвращенные оператором union, можно отсортировать с помощью предложения order by, следующего за вторым оператором select. Поскольку столбцы таблицы результатов запроса на объединение не имеют имен, в этом предложении следует указывать номера столбцов.

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

A UNION (В UNION С)

(A UNION В) UNION С

(A UNION С) UNION В

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

A UNION ALL (В UNION ALL С)

(A UNION ALL В) UNION ALL С

(A UNION ALL C) UNION ALL В

Однако если в запросы на объединения входят как операторы union, так и операторы union all, то порядок следования этих операторов имеет значение. Если выражение

A UNION ALL В UNION С

проинтерпретировать как

A UNION ALL (В UNION С)

то оно вернет десять строк (шесть из внутреннего оператора плюс четыре строки из таблицы А). Однако если его проинтерпретировать как

(A UNION ALL В) UNION С

то оно вернет только четыре строки, поскольку внешний оператор union удалит все повторяющиеся строки.

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