Результатом выполнения оператора 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
— применяются при необходимости для уточнения выборки и выполнения условий, группировки, фильтрации и сортировки данных. Эти дополнительные элементы позволяют гибко настраивать запросы и получать более точные результаты.