7.3. Списки выборки
Как говорилось в предыдущем разделе, табличное выражение в SELECT
создаёт промежуточную виртуальную таблицу, возможно объединяя таблицы, представления, группируя и исключая лишние строки и т. д. Полученная таблица передаётся для обработки в список выборки. Этот список выбирает, какие столбцы промежуточной таблицы должны выводиться в результате и как именно.
7.3.1. Элементы списка выборки
Простейший список выборки образует элемент *
, который выбирает все столбцы из полученного табличного выражения. Список выборки также может содержать список выражений значения через запятую (как определено в Разделе 4.2). Например, это может быть список имён столбцов:
SELECT a, b, c FROM ...
Имена столбцов a
, b
и c
представляют либо фактические имена столбцов таблиц, перечисленных в предложении FROM
, либо их псевдонимы, определённые как описано в Подразделе 7.2.1.2. Пространство имён в списке выборки то же, что и в предложении WHERE
, если не используется группировка. В противном случае оно совпадает с пространством имён предложения HAVING
.
Если столбец с заданным именем есть в нескольких таблицах, необходимо также указать имя таблицы, например так:
SELECT tbl1.a, tbl2.a, tbl1.b FROM ...
Обращаясь к нескольким таблицам, бывает удобно получить сразу все столбцы одной из таблиц:
SELECT tbl1.*, tbl2.a FROM ...
Подробнее запись имя_таблицы
.*
описывается в Подразделе 8.16.5.
Если в списке выборки используется обычное выражение значения, по сути при этом в возвращаемую таблицу добавляется новый виртуальный столбец. Выражение значения вычисляется один раз для каждой строки результата со значениями столбцов в данной строке. Хотя выражения в списке выборки не обязательно должны обращаться к столбцам табличного выражения из предложения FROM
; они могут содержать, например и простые арифметические выражения.
7.3.2. Метки столбцов
Элементам в списке выборки можно назначить имена для последующей обработки, например, для указания в предложении ORDER BY
или для вывода в клиентском приложении. Например:
SELECT a AS value, b + c AS sum FROM ...
Если выходное имя столбца не определено (с помощью AS
), система назначает имя сама. Для простых ссылок на столбцы этим именем становится имя целевого столбца, а для вызовов функций это имя функции. Для сложных выражений система генерирует некоторое подходящее имя.
Слово AS
обычно можно опустить, но в некоторых случаях, когда желаемое имя столбца совпадает с ключевым словом Postgres Pro, нужно написать AS
или заключить имя столбца в кавычки во избежание неоднозначности. (В Приложении C перечислены ключевые слова, для которых нужно использовать AS
в метке столбца.) Например, FROM
— ключевое слово, поэтому такой вариант не будет работать:
SELECT a from, b + c AS sum FROM ...
а любой из этих сработает:
SELECT a AS from, b + c AS sum FROM ... SELECT a "from", b + c AS sum FROM ...
Для предотвращения конфликта с ключевыми словами, которые могут появиться в будущем, рекомендуется всегда писать AS
или заключать метки выходных столбцов в кавычки.
Примечание
Именование выходных столбцов отличается от того, что происходит в предложении FROM
(см. Подраздел 7.2.1.2). Один столбец можно переименовать дважды, но на выходе окажется имя, назначенное в списке выборки.
7.3.3. DISTINCT
После обработки списка выборки в результирующей таблице можно дополнительно исключить дублирующиеся строки. Для этого сразу после SELECT
добавляется ключевое слово DISTINCT
:
SELECT DISTINCT список_выборки
...
(Чтобы явно включить поведение по умолчанию, когда возвращаются все строки, вместо DISTINCT
можно указать ключевое слово ALL
.)
Две строки считаются разными, если они содержат различные значения минимум в одном столбце. При этом значения NULL полагаются равными.
Кроме того, можно явно определить, какие строки будут считаться различными, следующим образом:
SELECT DISTINCT ON (выражение
[,выражение
...])список_выборки
...
Здесь выражение
— обычное выражение значения, вычисляемое для всех строк. Строки, для которых перечисленные выражения дают один результат, считаются дублирующимися и возвращается только первая строка из такого набора. Заметьте, что «первая строка» набора может быть любой, если только запрос не включает сортировку, гарантирующую однозначный порядок строк, поступающих в фильтр DISTINCT
. (Обработка DISTINCT ON
производится после сортировки ORDER BY
.)
Предложение DISTINCT ON
не описано в стандарте SQL и иногда его применение считается плохим стилем из-за возможной неопределённости в результатах. При разумном использовании GROUP BY
и подзапросов во FROM
можно обойтись без этой конструкции, но часто она бывает удобнее.