Результатом выполнения оператора SELECT является таблица, которую можно использовать для последующих запросов. Вложенные операторы SELECT, называемые подзапросами, позволяют выполнять более сложные выборки.
Синтаксис оператора SELECT использует следующие основные предложения:
SELECT <список столбцов>
FROM <список таблиц>
[WHERE <условие выбора строк>]
[GROUP BY <условие группировки>]
[HAVING <условие выбора групп>]
[ORDER BY <условие сортировки>]SELECT- выбирает данные из указанных столбцов и, при необходимости, выполняет преобразования с использованием выражений или функций.FROM- указывает таблицы, из которых берутся данные.WHERE- фильтрует строки, соответствующие заданным условиям.GROUP BY- группирует строки по указанным столбцам для получения агрегированных данных.HAVING- фильтрует группы, оставляя только те, которые удовлетворяют указанным условиямORDER BY- сортирует результат по указанным столбцам.
Из перечисленных элементов обязательными являются только SELECT и FROM.
Рассмотрим каждое предложение оператора SELECT.
База данных для примеров
Для всех дальнейших примеров будем использовать одну и ту же базу данных, чтобы сохранить последовательность и ясность. База данных будет охватывать предметную область "Поставка деталей".
Постановка задачи
Требуется разработать базу данных для предметной области "Поставка деталей", которая должна хранить следующую информацию:
- О поставщиках (P): номер поставщика (pnum) и имя поставщика (pname).
- О деталях (D): номер детали (pnum), название детали (dname), и её цена (dprice).
- О поставках (PD): информация о поставках, включая номер поставщика (pnum), номер детали (dnum), и объём поставки (volume).

Значения таблицы P
| pnum | pname |
|---|---|
| 1 | Иванов |
| 2 | Петров |
| 3 | Сидоров |
| 4 | Кузнецов |
Значения таблицы D
| pnum | dname | dprice |
|---|---|---|
| 1 | Болт | 10 |
| 2 | Гайка | 20 |
| 3 | Винт | 30 |
Значения таблицы PD
| pnum | dnum | volume |
|---|---|---|
| 1 | 1 | 100 |
| 1 | 2 | 100 |
| 1 | 3 | 300 |
| 2 | 1 | 150 |
| 1 | 2 | 250 |
| 3 | 1 | 1000 |
Предложение SELECT
SELECT — ключевое слово для выбора данных. После SELECT указываются столбцы, которые должны войти в результат, и порядок их указания влияет на удобство анализа. Имена столбцов указываются через запятую.
После служебного слова SELECT перечисляются имена столбцов, значения которых будут входить в результат выполнения запроса.
Столбцы в результирующей таблице размещаются в том порядке, в котором они были указаны в предложении SELECT. Имена столбцов указываются через запятую.
При работе с несколькими таблицами, где столбцы имеют одинаковые имена, используйте составные имена: <Имя таблицы>.<Имя столбца>, чтобы избежать двусмысленности и сделать код более читаемым и поддерживаемым.
Ниже приведён пример объединения нескольких таблиц с использованием составных имён:
SELECT P.pnum, P.pname, D.dname, PD.volume
FROM P
JOIN PD ON P.pnum = PD.pnum
JOIN D ON PD.dnum = D.pnum;В этом запросе используются составные имена, чтобы избежать путаницы при объединении таблиц, так как столбцы из разных таблиц могут иметь одинаковые названия.
Предложение FROM
В предложении FROM перечисляются имена таблиц, которые содержат столбцы, указанные после слова SELECT. Перечисление таблиц также определяет, откуда будут извлекаться данные и как они будут связаны в случае объединений.
Пример 1.
Вывести список наименований деталей из таблицы D ("Детали").
SELECT dname
FROM DПример 2.
Получить всю информацию из таблицы D (“Детали”).
Получить результат можно двумя способами:
-
Явным указанием всех столбцов таблицы.
SELECT dnum, dname, dprice FROM D -
Использование символа
*для выбора всех столбцов таблицы. Используйте*с осторожностью, чтобы избежать извлечения лишних данных, что может повлиять на производительность.SELECT * FROM D
В результате и первого, и второго запроса получаем новую таблицу, представляющую собой полную копию таблицы D ("Детали"). Можно также осуществить выбор отдельных столбцов и их перестановку.
Можно осуществить выбор отдельных столбцов и их перестановку.
Пример 3.
Получить информацию о наименовании и номере поставщика.
SELECT pname, pnum
FROM PПример 4.
Определить номера поставщиков, которые присутствуют в таблице PD ("Поставки").
SELECT pnum
FROM PDРезультат:
| pnum |
|---|
| 1 |
| 1 |
| 1 |
| 2 |
| 2 |
| 3 |
Дополнительно о SELECT
После изучения простых запросов с SELECT и FROM, рассмотрим агрегатные функции.
Агрегатные функции
Агрегатные функции используются в операторе SELECT для получения единственного значения, рассчитанного на основе группы строк. Агрегатная функция записывается как имя_функции(имя_столбца).
Доступные агрегатные функции:
SUM— вычисляет сумму значений указанного столбца;COUNT— вычисляет количество значений указанного столбца;MIN/MAX— определяет минимальное/максимальное значение в указанном столбце;AVG— вычисляет среднее значение значений столбца;
Пример 5.
Определить общий объём поставляемых деталей.
SELECT SUM(volume)
FROM PD
| Expr1000 |
|---|
| 2000 |
Столбцы, которых не существовало в исходных таблицах и которые были созданы при выполнении запроса, называются вычисляемыми столбцами. Таким столбцам СУБД присваивает системные имена.
При вычислении результатов любой агрегатной функции СУБД сначала исключает все NULL-значения, после чего операция применяется к оставшимся данным. Для функции COUNT существует особый вариант использования — COUNT(*), который подсчитывает все строки в результирующей таблице, включая NULL-значения.
MAX(SUM(VOLUME))Переименование столбца
Язык SQL позволяет задавать новые имена столбцам результирующей таблицы с помощью операции AS. Переименование также используют для упрощения сложных имён столбцов.
Например, присвоить новое имя вычисляемому столбцу в предыдущем примере можно следующим образом:
SELECT SUM(volume) AS SUM
FROM PD
| Sum |
|---|
| 2000 |
Пример 6.
Определить количество поставщиков, которые поставляют детали в настоящее время.
SELECT COUNT(pnum) AS COUNT
FROM PD
| Count |
|---|
| 6 |
Несмотря на то, что реальное число поставщиков деталей в таблице PD равно 3, СУБД возвращает число 6. Такой результат объясняется тем, что СУБД подсчитывает все строки в таблице PD, не обращая внимание на то, что в строках есть одинаковые значения.
Операция DISTINCT
Если до применения агрегатной функции необходимо исключить дублирующиеся значения, следует перед именем столбца указать ключевое слово DISTINCT.
SELECT COUNT(DISTINCT pnum) AS COUNT
FROM PD
| Count |
|---|
| 3 |
Ключевое слово DISTINCT можно использовать только один раз для одного предложения SELECT. Оно применяется только к столбцу, перед которым указано, и не влияет на другие столбцы в запросе.
Противоположностью DISTINCT является операция ALL. Обычно ALL не пишется явно в запросах, поскольку это поведение используется по умолчанию и имеет действие «показать все строки таблицы», включая дубликаты.
Операция TOP
Итоговый набор записей, получаемых после выполнения запроса, можно ограничить первыми N строками или первыми N процентами от общего количества строк результата. Для этого используется операция TOP, которая записывается в предложении SELECT следующим образом:
SELECT TOP N [PERCENT] <список столбцов>TOP используется только в некоторых диалектах SQL, например, в MS SQL Server, и может отсутствовать в других, таких как MySQL.Пример 7.
Определить номера первых двух деталей таблицы D.
SELECT TOP 2 dnum
FROM DСтандарт SQL требует, чтобы при сортировке NULL-значения трактовались либо как превосходящие, либо как уступающие по сравнению со всеми остальными значениями. Конкретный вариант стандартом не оговаривается, поэтому в зависимости от используемой СУБД при сортировке NULL-значения могут следовать до или после остальных значений.
Предложение WHERE
После служебного слова WHERE указываются условия выбора строк, которые будут помещены в результирующую таблицу. Существуют различные типы условий выбора:
- Сравнение значений атрибутов со скалярными выражениями, другими атрибутами или результатами вычисления выражений.
- Проверка на наличие
NULL-значения. - Проверка значения на принадлежность множеству.
- Проверка значения на принадлежность диапазону.
- Проверка строкового значения на соответствие шаблону.
Сравнение
В языке SQL используются традиционные операции сравнения: =, <>, <, <=, >, >=. В качестве условия в предложении WHERE можно использовать сложные логические выражения, включающие атрибуты таблиц, константы, скобки, а также операции AND, OR и отрицание NOT.
Пример 8.
Определить номера деталей, поставляемых поставщиком с номером 2.
SELECT dnum
FROM PD
WHERE pnum = 2Пример 9.
Получить информацию о поставщиках Иванов и Петров.
SELECT *
FROM P
WHERE pname='Иванов' OR pname='Петров'Проверка на принадлежность множеству
Операция IN проверяет, принадлежит ли значение атрибута заданному множеству.
Пример 10.
Получить информацию о поставщиках ‘Иванов’ и ‘Петров’.
SELECT *
FROM P
WHERE pname IN ('Иванов','Петров')Пример 11.
Получить информацию о деталях с номерами 1 и 2.
SELECT *
FROM D
WHERE dnum IN (1, 2)Проверка на принадлежность диапазону
Операция BETWEEN определяет минимальное и максимальное значение диапазона, в который должно попадать значение атрибута. Обе границы включены в диапазон.
Пример 12.
Определить номера деталей, с ценой от 10 до 20 рублей.
SELECT dnum
FROM D
WHERE dprice BETWEEN 10 AND 20Пример 13.
Вывести наименования поставщиков, начинающиеся с букв от «К» до «П»:
SELECT pname
FROM P
WHERE pname BETWEEN 'К' AND 'Р'
Буква «Р» в условии запроса используется, так как строки сравниваются посимвольно. Для каждого символа определяется его кодировка. В данном случае выполняется условие: П < Петров < Р.
Проверка строкового значения на соответствие шаблону
Операция LIKE используется для поиска подстрок. Значения столбца, указанного перед ключевым словом LIKE, сравниваются с шаблоном, заданным после него. Форматы шаблонов различаются в зависимости от конкретной СУБД.
Операция LIKE используется для поиска подстрок. Значения столбца, указываемого перед служебным словом LIKE сравниваются с задаваемым после него шаблоном. Форматы шаблонов различаются в конкретных СУБД.
Для СУБД MS SQL Server:
- Символ
%заменяет любое количество любых символов. - Символ
_заменяет один любой символ. [<множество символов>]— вместо символа строки может быть подставлен один любой символ из указанного множества.[^<множество символов>]— вместо символа строки может быть подставлен любой символ, кроме указанных в множестве.
Множество символов в квадратных скобках можно указывать через запятую или в виде диапазона.
Пример 14.
Вывести фамилии поставщиков, начинающихся с буквы И.
SELECT pname
FROM P
WHERE pname LIKE 'И%'Пример 15.
Вывести фамилии поставщиков, начинающихся с букв от К по П.
SELECT pname
FROM P
WHERE dname LIKE '[К-П]%'Проверка на наличие null-значения
Операции IS NULL и IS NOT NULL используются для проверки, имеет ли атрибут значение NULL или нет.
Пример 16.
Определить наименования деталей, для которых не указана цена.
SELECT dname
FROM D
WHERE dprice IS NULLПример 17.
Определить номера поставщиков, для которых указано наименование.
SELECT pnum
FROM P
WHERE pname IS NOT NULL
Предложение GROUP BY
Использование GROUP BY позволяет разбивать таблицу на логические группы и применять агрегатные функции к каждой из этих групп. В результате для каждой группы получается единственное значение.
GROUP BY используют, если в задаче присутствуют фразы вроде «для каждого…» или «каждому…».SELECT, должны присутствовать в предложении GROUP BY, за исключением тех, которые используются в агрегатных функциях.Пример 18.
Определить суммарный объем деталей, поставляемых каждым поставщиком.
SELECT pnum, SUM(VOLUME) AS SUM
FROM PD
GROUP BY pnum
| pnum | sum |
|---|---|
| 1 | 600 |
| 2 | 400 |
| 3 | 1000 |
При выполнении запроса СУБД разбивает таблицу PD на группы, каждая из которых включает строки с одинаковым номером поставщика. Затем к каждой группе применяется агрегатная функция SUM, возвращая итоговое значение для каждой группы.
Рассмотрим два похожих примера:
- В примере 19 определяется минимальный объем поставки для каждого поставщика.
- В примере 20 определяется минимальный объем поставки среди всех поставщиков.
Пример 19:
SELECT pnum, MIN(VOLUME) AS MIN
FROM PD
GROUP BY pnumПример 20:
SELECT MIN(VOLUME) AS MIN
FROM PРезультаты запросов представлены в следующей таблице:
| pnum | min | min |
|---|---|---|
| 1 | 100 | 100 |
| 2 | 150 | |
| 3 | 1000 |
MIN здесь применяется ко всей таблице, а не к отдельным группам.GROUP BY может содержать имена столбцов, не указанные в списке вывода после ключевого слова SELECT. Если GROUP BY используется после WHERE, то группы создаются на основании строк, выбранных после применения условия WHERE.
Пример 21.
Для каждой из деталей с номерами 1 и 2 определить количество поставщиков, которые их поставляют, а также суммарный объем поставок:
SELECT dnum, COUNT(pnum) AS COUNT, SUM(volume) AS SUM
FROM PD
WHERE dnum=1 OR dnum=2
GROUP BY dnumРезультат запроса:
| dnum | COUNT | SUM |
|---|---|---|
| 1 | 3 | 1250 |
| 2 | 2 | 450 |
Чтобы организовать вложенные группировки, после GROUP BY следует указать несколько группирующих столбцов через запятую. В этом случае реальный подсчет данных будет происходить по той группе, которая указана последней.
Предложение HAVING
Предложение HAVING задает условие, согласно которому определенные группы, сформированные с помощью GROUP BY, исключаются из результирующей таблицы. Выполнение HAVING схоже с выполнением WHERE, но между ними есть важное различие:
WHEREисключает строки до того, как выполняется группировка.HAVINGприменяется после группировки, поэтому в нем могут использоваться агрегатные функции, в отличие отWHERE, где агрегатные функции недопустимы.
Пример 22.
Определить номера поставщиков, поставляющих в сумме более 500 деталей:
SELECT pnum, SUM(volume) AS SUM
FROM PD
GROUP BY pnum
HAVING SUM(volume) > 500
| pnum | SUM |
|---|---|
| 1 | 600 |
| 3 | 1000 |
Пример 23.
Определить номера поставщиков, которые поставляют только одну деталь:
SELECT pnum, COUNT(dnum) AS COUNT
FROM PD
GROUP BY pnum
HAVING COUNT(dnum) = 1
| pnum | SUM |
|---|---|
| 3 | 1 |
Предложение ORDER BY
При выполнении запроса СУБД возвращает строки в случайном порядке. Предложение ORDER BY позволяет упорядочить выходные данные запроса по значениям одного или нескольких столбцов. Можно задать сортировку по возрастанию — ASC (от Ascend) или по убыванию — DESC (от Descend). По умолчанию используется сортировка по возрастанию.
Пример 24.
Отсортировать таблицу PD в порядке возрастания номеров поставщиков. Строки с одинаковым значением pnum отсортировать в порядке убывания объема поставок:
SELECT pnum, volume, dnum
FROM PD
ORDER BY pnum ASC, volume DESC
| pnum | volume | dnum |
|---|---|---|
| 1 | 300 | 3 |
| 1 | 200 | 2 |
| 1 | 100 | 1 |
| 2 | 250 | 2 |
| 2 | 150 | 1 |
| 3 | 1000 | 1 |
TOP удобно применять после сортировки результирующего набора с помощью предложения ORDER BY.Пример 25.
Вывести номера первых двух деталей с наименьшей стоимостью:
SELECT TOP 2 dnum
FROM D
ORDER BY dprice ASCЕсли в таблице D есть детали без указания цены (NULL), то запрос отобразит именно их, так как NULL сортируются перед ненулевыми значениями в порядке возрастания. Чтобы исключить строки с NULL, добавьте условие WHERE:
SELECT TOP 2 dnum
FROM D
WHERE dprice IS NOT NULL
ORDER BY dprice ASC
Заключение
В статье рассмотрены ключевые аспекты использования оператора SELECT для выполнения запросов в SQL. Понимание и уверенное владение оператором SELECT является основой для написания любых SQL-запросов, так как он позволяет выбирать данные из таблиц и формировать результат в соответствии с требованиями, используя выражения и функции.
Результатом выполнения оператора SELECT всегда является таблица, которую можно использовать как подзапрос в других запросах, что позволяет строить сложные запросы и фильтровать данные на нескольких уровнях.
Синтаксис SELECT включает несколько предложений, из которых обязательными являются только SELECT и FROM. Остальные — WHERE, GROUP BY, HAVING и ORDER BY — применяются при необходимости для уточнения выборки и выполнения условий, группировки, фильтрации и сортировки данных. Эти дополнительные элементы позволяют гибко настраивать запросы и получать более точные результаты.

