Оператор SELECT

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

· 9 минуты на чтение

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

Синтаксис оператора SELECT использует следующие основные предложения:

SELECT <список столбцов>
FROM <список таблиц>
[WHERE <условие выбора строк>]
[GROUP BY <условие группировки>]
[HAVING <условие выбора групп>]
[ORDER BY <условие сортировки>]
  • SELECT - выбирает данные из указанных столбцов и, при необходимости, выполняет преобразования с использованием выражений или функций.
  • FROM - указывает таблицы, из которых берутся данные.
  • WHERE - фильтрует строки, соответствующие заданным условиям.
  • GROUP BY - группирует строки по указанным столбцам для получения агрегированных данных.
  • HAVING - фильтрует группы, оставляя только те, которые удовлетворяют указанным условиям
  • ORDER BY - сортирует результат по указанным столбцам.

Из перечисленных элементов обязательными являются только SELECT и FROM.

Рассмотрим каждое предложение оператора SELECT.

Спонсор поста

База данных для примеров

Для всех дальнейших примеров будем использовать одну и ту же базу данных, чтобы сохранить последовательность и ясность. База данных будет охватывать предметную область "Поставка деталей".

Постановка задачи

Требуется разработать базу данных для предметной области "Поставка деталей", которая должна хранить следующую информацию:

  1. О поставщиках (P): номер поставщика (pnum) и имя поставщика (pname).
  2. О деталях (D): номер детали (pnum), название детали (dname), и её цена (dprice).
  3. О поставках (PD): информация о поставках, включая номер поставщика (pnum), номер детали (dnum), и объём поставки (volume).

Значения таблицы P

pnumpname
1Иванов
2Петров
3Сидоров
4Кузнецов

Значения таблицы D

pnumdnamedprice
1Болт10
2Гайка20
3Винт30

Значения таблицы PD

pnumdnumvolume
11100
12100
13300
21150
12250
311000

Предложение 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-значения могут следовать до или после остальных значений.

Спонсор поста 3

Предложение 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
pnumsum
1600
2400
31000

При выполнении запроса СУБД разбивает таблицу PD на группы, каждая из которых включает строки с одинаковым номером поставщика. Затем к каждой группе применяется агрегатная функция SUM, возвращая итоговое значение для каждой группы.

Рассмотрим два похожих примера:

  • В примере 19 определяется минимальный объем поставки для каждого поставщика.
  • В примере 20 определяется минимальный объем поставки среди всех поставщиков.

Пример 19:

SELECT pnum, MIN(VOLUME) AS MIN
FROM PD
GROUP BY pnum

Пример 20:

SELECT MIN(VOLUME) AS MIN
FROM P

Результаты запросов представлены в следующей таблице:

pnumminmin
1100100
2150
31000
Обратите внимание, что в первом примере мы можем вывести номера поставщиков, соответствующие минимальным объемам поставок, а во втором — нет, так как агрегатная функция 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

Результат запроса:

dnumCOUNTSUM
131250
22450

Чтобы организовать вложенные группировки, после 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
pnumSUM
1600
31000

Пример 23.
Определить номера поставщиков, которые поставляют только одну деталь:

SELECT pnum, COUNT(dnum) AS COUNT
FROM PD
GROUP BY pnum
HAVING COUNT(dnum) = 1
pnumSUM
31

Предложение ORDER BY

При выполнении запроса СУБД возвращает строки в случайном порядке. Предложение ORDER BY позволяет упорядочить выходные данные запроса по значениям одного или нескольких столбцов. Можно задать сортировку по возрастанию — ASC (от Ascend) или по убыванию — DESC (от Descend). По умолчанию используется сортировка по возрастанию.

Пример 24.
Отсортировать таблицу PD в порядке возрастания номеров поставщиков. Строки с одинаковым значением pnum отсортировать в порядке убывания объема поставок:

SELECT pnum, volume, dnum
FROM PD
ORDER BY pnum ASC, volume DESC
pnumvolumednum
13003
12002
11001
22502
21501
310001
Операцию 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 — применяются при необходимости для уточнения выборки и выполнения условий, группировки, фильтрации и сортировки данных. Эти дополнительные элементы позволяют гибко настраивать запросы и получать более точные результаты.

Struchkov Mark
Struchkov Mark
Задавайте вопросы, если что-то осталось не понятным👇