Представим, что мы хотим узнать, на какие курсы онлайн-школы записались студенты. Для этого нам нужно выполнить запрос на выборку из таблицы course_members:
SELECT course_id FROM course_members ORDER BY course_id;
| course_id |
|---|
| 2 |
| 10 |
| 12 |
| 12 |
| 15 |
| ... |
View on DB Fiddle
Мы выбрали идентификаторы всех курсов, на которые записался хотя бы один студент. Видно, что некоторые идентификаторы курсов повторяются — на них записалось по несколько студентов.
Сейчас мы изучаем только сами курсы, не обращая внимания на количество записавшихся студентов. Поэтому нам нужно убрать повторяющиеся идентификаторы и оставить только уникальные.
В этом уроке мы разберемся, как это сделать.
Как убрать повторяющиеся строки
В языке SQL существует специальный оператор DISTINCT, который удаляет повторяющиеся строки запроса и оставляет только уникальные. Запрос будет выглядеть так:
SELECT DISTINCT course_id FROM course_members ORDER BY course_id;
| course_id |
|---|
| 2 |
| 10 |
| 12 |
| 15 |
| ... |
View on DB Fiddle
Теперь из этого запроса исключены все повторяющиеся строки.
Таким образом, чтобы исключить повторяющиеся строки, нужно после оператора SELECT указать DISTINCT и перечислить все нужные столбцы.
Если мы добавим в наш запрос еще одно поле user_id, то это изменит результат запроса. В эту выборку попадут строки с уникальным сочетанием курса и слушателя.
По отдельности курсы и слушатели могут повторяться, но их сочетание будет уникальным:
-- DISTINCT добавляется в запрос только один раз,
-- независимо от того, сколько колонок перечисляется
SELECT DISTINCT
course_id,
user_id
FROM course_members ORDER BY course_id;
| course_id | user_id |
|---|---|
| 2 | 5 |
| 10 | 19 |
| 12 | 4 |
| 12 | 65 |
| 15 | 31 |
View on DB Fiddle
Оператор DISTINCT ON
Представим, что мы хотим выбрать уникальные курсы и добавить дату, когда на него записался первый студент.
Напишем запрос, в котором после DISTINCT укажем course_id и created_at. Он вернет нам уникальные сочетания этих двух полей:
SELECT DISTINCT course_id, created_at FROM course_members ORDER BY course_id;
| course_id | created_at |
|---|---|
| 2 | 2022-06-14T10:48:45.491Z |
| 10 | 2022-06-14T06:40:23.565Z |
| 12 | 2022-06-14T11:36:10.374Z |
| 12 | 2022-06-13T21:41:33.465Z |
| 15 | 2022-06-14T13:21:58.235Z |
| ... |
View on DB Fiddle
Есть модификация этого оператора — DISTINCT ON. Такой вариант оператора позволяет указать:
- Поле, которое должно быть уникальным.
- Поля, которые нужно вывести.
Так выглядит запрос с DISTINCT ON:
SELECT DISTINCT ON (course_id)
course_id,
created_at
FROM course_members
ORDER BY course_id, created_at;
View on DB Fiddle
После DISTINCT ON в круглых скобках мы указываем поле, по которому будет проверяться уникальность. Далее мы перечисляем те поля, которые мы хотим видеть в запросе.
В нашем запросе идентификаторы курсов не повторяются, а в качестве created_at выводится первая дата выбора курса.
В DISTINCT ON можно указывать несколько полей в качестве уникальных:
SELECT DISTINCT ON (course_id, created_at)
course_id,
created_at
FROM course_members
ORDER BY course_id;
View on DB Fiddle
Такой запрос будет равносилен первому запросу этого раздела:
SELECT DISTINCT
course_id,
created_at
FROM course_members ORDER BY course_id;
Сортировка с оператором DISTINCT ON
При работе с DISTINCT ON важно правильно использовать сортировку. Первыми полями в ORDER BY должны быть те, которые идут после DISTINCT ON.
Для примера напишем еще один запрос — к каждому уникальному курсу выведем дату, в которую записался последний студент.
Для этого нужно после ORDER BY сначала указать поле course_id, как того требует синтаксис. Затем нужно добавить поле created_at с сортировкой по убыванию:
SELECT DISTINCT ON (course_id)
course_id,
created_at
FROM course_members
ORDER BY course_id, created_at DESC;
View on DB Fiddle
Этот запрос выведет все уникальные курсы и дату, когда на этот курс в последний раз записывались.
Выводы
В этом уроке мы изучили оператор DISTINCT и научились с помощью него выбирать уникальные строки и удалять дублирующиеся. Кроме того, мы разобрались с модификацией DISTINCT ON, научились задавать уникальные поля и добавлять к ним дополнительную информацию.
В следующих уроках мы научимся некоторым функциям, которые часто используются вместе с оператором DISTINCT.