Select (SQL)

SELECT (от англ. select — «выбрать») — оператор запроса (DML/DQL) в языке SQL, возвращающий набор данных (выборку) из базы данных.

Оператор возвращает ноль или более строк. Список возвращаемых столбцов задается в части оператора, называемой предложением SELECT. Поскольку SQL является декларативным языком, запрос SELECT определяет лишь требования к возвращаемому набору данных, но не является точной инструкцией по их вычислению. СУБД транслирует запрос SELECT во внутренний план исполнения («query plan»), который может различаться даже для синтаксически одинаковых запросов и от конкретной СУБД.

Оператор SELECT состоит из нескольких предложений (разделов):

  • SELECT определяет список возвращаемых столбцов (как существующих, так и вычисляемых), их имена, ограничения на уникальность строк в возвращаемом наборе, ограничения на количество строк в возвращаемом наборе;
  • FROM задаёт табличное выражение, которое определяет базовый набор данных для применения операций, определяемых в других предложениях оператора;
  • WHERE задает ограничение на строки табличного выражения из предложения FROM;
  • GROUP BY объединяет ряды, имеющие одинаковое свойство с применением агрегатных функций
  • HAVING выбирает среди групп, определённых параметром GROUP BY
  • ORDER BY задает критерии сортировки строк; отсортированные строки передаются в точку вызова.

Структура оператора

[править | править код]

Оператор SELECT имеет следующую структуру:

SELECT   [DISTINCT | DISTINCTROW | ALL]   select_expression,... FROM table_references [WHERE where_definition] [GROUP BY {unsigned_integer | col_name | formula}] [HAVING where_definition] [ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC], ...] 

Предложения оператора

[править | править код]

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

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

Предложение [[WHERE (SQL)|WHERE]] используется для определения, какие строки должны быть выбраны из табличного выражения в предложении FROM.

[[GROUP BY (SQL)|GROUP BY]] — необязательное предложение оператора SELECT, для группировки строк по результатам агрегатных функций (MAX, SUM, AVG, …).

Необходимо, чтобы в предложении SELECT были заданы только требуемые в выходном потоке столбцы, перечисленные в GROUP BY и/или агрегированные значения. Распространённая ошибка — указание в предложении SELECT столбца, пропущенного в GROUP BY.

HAVING — необязательное предложение оператора SELECT для отбора групп, получающихся в результате GROUP BY.

При указании HAVING <условия> можно указывать условия на столбцах, указанных в GROUP BY, и значениях агрегатных функций, вычисленных для каждой группы, образованной GROUP BY.

ORDER BY — необязательное предложение операторов SELECT и UNION, который означает что операторы SELECT, UNION возвращают набор строк, отсортированных по значениям одного или более столбцов. Его можно применять как к числовым столбцам, так и к строковым. В последнем случае, сортировка будет происходить по алфавиту.

Использование предложения ORDER BY является единственным способом отсортировать результирующий набор строк. Без этого предложения СУБД может вернуть строки в любом порядке. Если упорядочение необходимо, ORDER BY должен присутствовать в SELECT, UNION.

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

  • Параметр ASC (по умолчанию) устанавливает порядок сортировки по возрастанию, от меньших значений к большим.
  • Параметр DESC устанавливает порядок сортировки по убыванию, от больших значений к меньшим.
Таблица «T» Запрос Результат
C1 C2
1 a
2 b
SELECT * FROM T 
C1 C2
1 a
2 b
C1 C2
1 a
2 b
SELECT C1 FROM T 
C1
1
2
C1 C2
1 a
2 b
SELECT * FROM T WHERE C1 = 1 
C1 C2
1 a
C1 C2
1 a
2 b
SELECT * FROM T ORDER BY C1 DESC 
C1 C2
2 b
1 a

Для таблицы T запрос

SELECT * FROM T 

вернёт все столбцы всех строк данной таблицы. Для той же таблицы запрос

SELECT C1 FROM T 

вернёт значения столбца C1 всех строк таблицы. В терминах реляционной алгебры можно сказать, что была выполнена проекция. Для той же таблицы запрос

SELECT * FROM T WHERE C1 = 1 

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

SELECT * FROM T ORDER BY C1 DESC 

вернёт те же строки, что и первый, однако результат будет отсортирован в обратном порядке (Z-A) из-за использования ключевого слова ORDER BY с полем C1 в качестве поля сортировки. Этот запрос не содержит ключевого слова WHERE, поэтому он вернёт всё, что есть в таблице. Несколько элементов ORDER BY могут быть указаны разделённые запятыми [напр. ORDER BY C1 ASC, C2 DESC] для более точной сортировки.

Отбирает все строки, где поле column_name равно одному из перечисленных значений value1, value2,…

SELECT * FROM   table_name WHERE   column_name IN (value1, value2, ...) 

Возвращает список идентификаторов отделов, продажи которых превысили 1000 за 1 января 2000 года, вместе с суммами продаж за этот день:

SELECT   DeptID,   SUM(SaleAmount) FROM   Sales WHERE   SaleDate = '01-Jan-2000' GROUP BY   DeptID HAVING   SUM(SaleAmount) > 1000 

Ограничение возвращаемых строк

[править | править код]

Согласно ISO SQL:2003 возвращаемый набор данных может быть ограничен с помощью:

  • курсоров, или
  • введением оконных функций в оператор SELECT

Оконная функция ROW_NUMBER()

[править | править код]

Существуют различные оконные функции. ROW_NUMBER() OVER может быть использована для простого ограничения числа возвращаемых строк. Например, для возврата не более десяти строк:

SELECT * FROM (   SELECT     ROW_NUMBER() OVER (ORDER BY key ASC) AS rownumber,     columns   FROM tablename ) AS foo WHERE rownumber <= 10 

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

Оконная функция RANK()

[править | править код]

Функция RANK() OVER работает почти так же, как ROW_NUMBER, но может вернуть более чем n строк при определённых условиях. Например, для получения top-10 самых молодых людей:

SELECT * FROM (   SELECT     RANK() OVER (ORDER BY age ASC) AS ranking,     person_id,     person_name,     age   FROM person ) AS foo WHERE ranking <= 10 

Данный код может вернуть более чем 10 строк. Например, если есть два человека с одинаковым возрастом, он вернёт 11 строк.

Нестандартный синтаксис

[править | править код]

Не все СУБД поддерживают вышеуказанные оконные функции. При этом многие имеют нестандартный синтаксис для решения тех же задач. Ниже представлены варианты простого ограничения выборки для различных СУБД:

Производитель/СУБД Синтаксис ограничения
DB2 (Поддерживает стандарт, начиная с DB2 Version 6)
SELECT * FROM [T] FETCH FIRST 10 ROWS ONLY 
Firebird
SELECT FIRST 10 * FROM [T] 
Informix
SELECT FIRST 10 * FROM [T] 
Interbase
SELECT * FROM [T] ROWS 10 
Microsoft (Поддерживает стандарт, начиная с SQL Server 2005)
Также
SELECT TOP 10 [PERCENT] * FROM T ORDER BY col 
MySQL
SELECT * FROM T LIMIT 10 
SQLite
SELECT * FROM T LIMIT 10 
PostgreSQL (Поддерживает стандарт, начиная с PostgreSQL 8.4)
SELECT * FROM T LIMIT 10 
Oracle (Поддерживает стандарт, начиная с Oracle8i)
Также
SELECT * FROM T WHERE ROWNUM <= 10 

Литература

[править | править код]
  • Chamberlin, Donald D. Early history of SQL. // IEEE Annals of the History of Computing 34.4 (2012): 78-82. (англ.)
  • Alex Kriegel, Boris M. Trukhnov. SQL Bible (2nd ed.). Wiley Publishing, 2008. (англ.)
  • Грубер М. Понимание SQL. — Москва, 1993. — 291 с.