Знакомство с инструкцией SELECT

Завершено

Transact-SQL или T-SQL — разновидность языка SQL стандарта ANSI, используемого продуктами и службами Microsoft SQL. Он аналогичен стандартному SQL. Большая часть внимания здесь будет уделяться инструкции SELECT, которая обладает большей частью возможностей и вариаций любой инструкции DML.

Начнем с подробного обзора того, как обрабатывается инструкция SELECT. Порядок содержимого в инструкции SELECT не является порядком, в котором она обрабатывается ядром СУБД SQL Server.

Обратите внимание на следующий запрос:

SELECT OrderDate, COUNT(OrderID) AS Orders
FROM Sales.SalesOrder
WHERE Status = 'Shipped'
GROUP BY OrderDate
HAVING COUNT(OrderID) > 1
ORDER BY OrderDate DESC;

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

Предложение SELECT возвращает столбец OrderDate и количество значений OrderID , которому присваивается имя (или псевдоним) Orders:

SELECT OrderDate, COUNT(OrderID) AS Orders

Предложение FROM определяет, какая таблица является источником строк для запроса; В этом случае это таблица Sales.SalesOrder :

FROM Sales.SalesOrder

Предложение WHERE фильтрует строки из результатов, сохраняя только те строки, которые соответствуют указанному условию; в данном случае это заказы с состоянием "shipped":

WHERE Status = 'Shipped'

Предложение GROUP BY принимает строки, которые соответствуют условию фильтра и группируют их по OrderDate, чтобы все строки с одинаковым OrderDate считались одной группой, и одна строка будет возвращена для каждой группы:

GROUP BY OrderDate

После формирования групп предложение HAVING фильтрует группы на основе собственного предиката. В результаты будут включаться только даты с более чем одним заказом:

HAVING COUNT(OrderID) > 1

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

ORDER BY OrderDate DESC;

Теперь, когда вы видели, что делает каждое предложение, давайте посмотрим на порядок, в котором SQL Server действительно оценивает их:

  1. Сначала вычисляется предложение FROM, чтобы предоставить исходные строки для остальной части инструкции. Создается виртуальная таблица, и затем передается на следующий шаг.
  2. Далее необходимо вычислить предложение WHERE, чтобы отфильтровать строки из исходной таблицы, соответствующие предикату. Отфильтрованная виртуальная таблица передается на следующий шаг.
  3. Здесь предложение GROUP BY упорядочивает строки в виртуальной таблице в соответствии с уникальными значениями, найденными в списке GROUP BY. Создается новая виртуальная таблица, содержащая список групп, и она передается на следующий шаг. С этого момента в потоке операций другие элементы могут ссылаться только на столбцы в списке GROUP BY или функциях агрегации.
  4. Далее вычисляется предложение HAVING путем фильтрации целых групп на основе его предиката. Виртуальная таблица, созданная на шаге 3, фильтруется и передается на следующий шаг.
  5. В конце выполняется предложение SELECT, определяя, какие столбцы будут отображаться в результатах запроса. Так как предложение SELECT вычисляется после других шагов, все псевдонимы столбцов (в нашем примере Заказы) не могут использоваться в предложении GROUP BY или HAVING.
  6. Предложение ORDER BY является последним выполняемым и оно сортирует строки согласно списку столбцов.

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

FROM Sales.SalesOrder
WHERE Status = 'Shipped'
GROUP BY OrderDate 
HAVING COUNT(OrderID) > 1
SELECT OrderDate, COUNT(OrderID) AS Orders
ORDER BY OrderDate DESC;

Не все возможные предложения необходимы во всех используемых инструкциях SELECT. Единственным обязательным предложением является предложение SELECT, которое в некоторых случаях можно использовать самостоятельно. Обычно для указания запрашиваемой таблицы также добавляется предложение FROM. Кроме того, в языке Transact-SQL есть другие предложения, которые можно добавить.

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

Выбор всех столбцов

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

Простейшая форма предложения SELECT: использовать символ звездочки (*), чтобы вернуть все столбцы. При использовании в запросах T-SQL он называется звездой. Хотя SELECT * подходит для быстрой проверки, не следует использовать его в рабочей среде по нижеуказанным причинам.

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

Например, в следующем примере извлекаются все столбцы из таблицы Production.Product (гипотетический).

SELECT * FROM Production.Product;

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

ProductID

Имя.

НомерПродукта

Цвет

Стандартная стоимость

ПрейскурантнаяЦена

Размер

Вес

ProductCatID

680

HL Road Frame - Black, 58

FR-R92B-58

Черный

1059.31

1431.5

58

1016.04

18

706

Рама для дорожного велосипеда HL - красная, 58

FR-R92R-58

Красный

1059.31

1431.5

58

1016.04

18

707

Шлем Sport-100, красный

HL-U509-R

Красный

13.0863

34.99

35

708

Шлем Sport-100, черный

HL-U509

Черный

13.0863

34.99

35

...

...

...

...

...

...

...

...

...

Выбор конкретных столбцов

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

Например, рассмотрим следующий запрос; который снова использует гипотетические таблицы Production.Product .

SELECT ProductID, Name, ListPrice, StandardCost
‎FROM Production.Product;

На этот раз результаты содержат только указанные столбцы:

ProductID

Имя.

ПрейскурантнаяЦена

Стандартная стоимость

680

HL Road Frame - Black, 58

1431.5

1059.31

706

Каркас дорожного велосипеда HL, красный, размер 58.

1431.5

1059.31

707

Шлем Sport-100, красный

34.99

13.0863

708

Шлем Sport-100, черный

34.99

13.0863

...

...

...

...

Выбор выражений

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

Например, следующий запрос содержит два выражения:

SELECT ProductID,
      Name + '(' + ProductNumber + ')',
  ListPrice - StandardCost
FROM Production.Product;

Результаты этого запроса могут выглядеть примерно так:

ProductID

680

HL Road Frame - Black, 58(FR-R92B-58)

372.19

706

HL Road Frame - Red, 58(FR-R92R-58)

372.19

707

Спорт-100 Шлем, Red(HL-U509-R)

21.9037

708

Спорт-100 Шлем, Черный(HL-U509)

21.9037

...

...

...

Здесь следовало бы отметить несколько интересных особенностей.

  • Столбцы, возвращаемые двумя выражениями, не имеют имен столбцов. В зависимости от инструмента, используемого для отправки запроса, отсутствует имя столбца может быть указано пустым заголовком столбца, литеральным индикатором "без имени столбца" или именем по умолчанию, например column1. Мы посмотрим, как указать псевдоним для имени столбца в запросе далее в этом разделе.
  • Первое выражение использует оператор + для (посимвольного) сцепления значений, а второе выражение использует оператор - для вычитания одного числового значения из другого. При использовании с числовыми значениями оператор + выполняет сложение. Очевидно, что важно понимать типы данных столбцов, которые вы включаете в выражения. Типы данных мы рассмотрим в следующем разделе.

Указание псевдонимов столбцов

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

Например, вот тот же запрос, что и раньше, но с псевдонимами, указанными для каждого столбца:

SELECT ProductID AS ID,
      Name + '(' + ProductNumber + ')' AS ProductName,
  ListPrice - StandardCost AS Markup
FROM Production.Product;

Результаты этого запроса содержат указанные имена столбцов:

Идентификатор

НаименованиеПродукта

Разметка

680

HL Road Frame - Black, 58(FR-R92B-58)

372.19

706

HL Дорожная рама - красная, 58(FR-R92R-58)

372.19

707

Спорт-100 Шлем, Red(HL-U509-R)

21.9037

708

Спорт-100 Шлем, Черный(HL-U509)

21.9037

...

...

...

Примечание.

Ключевое слово AS является необязательным при указании псевдонима, но для ясности рекомендуется включать его.

Форматирование запросов

Из примеров этого раздела можно увидеть, что в форматировании кода запроса есть определенная гибкость. Например, каждое предложение (или весь запрос) можно написать одной строкой или разбить на несколько строк. В большинстве систем баз данных код не учитывает регистр, а некоторые элементы языка T-SQL являются необязательными (включая ключевое слово AS, как упоминалось ранее, и даже точку с запятой в конце инструкции).

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

  • Записывайте прописью ключевые слова T-SQL, например SELECT, FROM, AS и т. д. Ключевые слова прописью — это часто используемое соглашение, которое упрощает поиск предложений в сложной инструкции.
  • Начинайте каждое основное предложение инструкции с новой строки.
  • Если список SELECT содержит больше нескольких столбцов, выражений или псевдонимов, рекомендуем перечислять каждый столбец в отдельной строке.
  • Используйте отступы для строк, содержащих вложенные предложения или столбцы, чтобы показать, какой код относится к какому основному предложению.