Иногда базы данных напоминают человека с плохой памятью — всё записывает, но забывает, что уже записал. В итоге вы открываете таблицу с городами клиентов, а там десять "Берлинов", пять "Сиэтлов" и куча других повторов. Такое бывает, если один и тот же город встречается у разных клиентов. Но вы же не хотите строить рекламную кампанию по десяти "Берлинам", когда это всего один город, правда?
Чтобы вытащить только уникальные значения — без дубликатов — есть удобная команда DISTINCT. Она как волшебная швабра: одним взмахом убирает повторяющиеся строки и оставляет только то, что действительно отличается.
DISTINCT позволяет извлекать только уникальные строки из результата запроса. Это полезно в ситуациях, когда вам нужно избавиться от повторяющихся данных, таких как:
- Уникальные товары в заказах.
- Уникальные имена клиентов.
- Уникальные комбинации данных, например "город + страна".
Как работает DISTINCT?
Синтаксис DISTINCT простой и понятный, как чаще всего с SQL и бывает:
SELECT DISTINCT колонка1, колонка2, ...
FROM таблица;
Когда вы добавляете DISTINCT в запрос, база данных гарантирует, что каждая строка в результате будет уникальной.
Примеры использования DISTINCT
Начнём с классических примеров, чтобы понять, как работает DISTINCT.
Пример 1: Уникальные значения одного столбца
Пусть у нас есть таблица students с данными о студентах:
-- Таблица students
| id | first_name | last_name | city |
|---|---|---|---|
| 1 | Maria | Chi | Seattle |
| 2 | Alex | Lin | Toronto |
| 3 | Anna | Song | Seattle |
| 4 | Nat | Cole | Chicago |
| 5 | Maria | Chi | Seattle |
Мы хотим узнать, из каких городов приезжают студенты. Пишем запрос
SELECT city
FROM students;
и получаем результат:
| city |
|---|
| Seattle |
| Toronto |
| Seattle |
| Chicago |
| Seattle |
Немного не то, что мы хотели :(
Чтобы устранить дубликаты нужно использовать DISTINCT:
SELECT DISTINCT city
FROM students;
Результат:
| city |
|---|
| Seattle |
| Toronto |
| Chicago |
Без DISTINCT в результате мы увидим повторения "Seattle" трижды, а нам нужно было всего по одному разу.
Пример 2: Уникальные значения нескольких столбцов
Теперь представим, что мы хотим получить уникальные комбинации "имя + фамилия", ведь среди студентов могут быть однофамильцы или одноимённые люди.
Пусть у нас есть та же таблица students:
-- Таблица students
| id | first_name | last_name | city |
|---|---|---|---|
| 1 | Maria | Chi | Seattle |
| 2 | Alex | Lin | Toronto |
| 3 | Anna | Song | Seattle |
| 4 | Nat | Cole | Chicago |
| 5 | Maria | Chi | Seattle |
Запрос:
SELECT DISTINCT first_name, last_name
FROM students;
Результат:
| first_name | last_name |
|---|---|
| Maria | Chi |
| Alex | Lin |
| Anna | Song |
| Nat | Cole |
Таким образом, DISTINCT работает как фильтр: он учитывает все указанные столбцы и исключает повторы только тех строк, где значения всех этих столбцов совпадают.
Пример 3: Уникальные комбинации и сортировка
Теперь мы комбинируем DISTINCT с сортировкой ORDER BY, чтобы получить уникальные значения, упорядоченные в алфавитном порядке по фамилии.
Пусть у нас есть таблица students:
-- Таблица students
| id | first_name | last_name | city |
|---|---|---|---|
| 1 | Maria | Chi | Seattle |
| 2 | Alex | Lin | Toronto |
| 3 | Anna | Song | Seattle |
| 4 | Nat | Cole | Chicago |
| 5 | Maria | Chi | Seattle |
Запрос:
SELECT DISTINCT first_name, last_name
FROM students
ORDER BY last_name ASC;
Результат:
| first_name | last_name |
|---|---|
| Maria | Chi |
| Nat | Cole |
| Alex | Lin |
| Anna | Song |
Дублирующиеся строки удалены, а фамилии отсортированы по алфавиту.
Пример 4: Использование на агрегациях
Что, если мы попытаемся применить DISTINCT к функции, например, COUNT?
SELECT COUNT(DISTINCT city) AS unique_city_count
FROM students;
Результат:
| unique_city_count |
|---|
| 3 |
Этот запрос вернёт количество уникальных городов. Удобно, правда?
Особенности работы DISTINCT
При использовании DISTINCT важно понимать, что он работает по всем указанным столбцам. Если вы добавите больше столбцов в запрос, результат может измениться.
Пример 5: Почему так важно понимать контекст?
Если вы добавите в запрос дополнительные поля, это может повлиять на уникальность строк.
SELECT DISTINCT first_name, city
FROM students;
Таблица students:
| id | first_name | last_name | city |
|---|---|---|---|
| 1 | Maria | Chi | Seattle |
| 2 | Alex | Lin | Austin |
| 3 | Anna | Song | Seattle |
| 4 | Otto | Art | Denver |
| 5 | Maria | Chi | Portland |
Результат:
| first_name | city |
|---|---|
| Maria | Seattle |
| Alex | Austin |
| Anna | Seattle |
| Otto | Denver |
| Maria | Portland |
Каждая комбинация "имя + город" теперь уникальна. Поэтому помните: уникальность определяется всеми указанными столбцами, а не каждым столбцом по отдельности.
Типичные ошибки при работе с DISTINCT
Одной из самых распространённых ошибок при использовании DISTINCT является неправильное понимание того, что именно делает запрос. Например, если в запросе указать слишком много столбцов, вы можете получить результат, который далёк от ожидаемого, потому что уникальность будет определяться по всем столбцам.
Например:
SELECT DISTINCT *
FROM students;
В этом случае каждая строка будет считаться уникальной, потому что все столбцы учитываются.
Ещё одна ошибка — использовать DISTINCT там, где он не нужен. Если вы уверены, что данные уже уникальны (например, столбец, являющийся первичным ключом), то DISTINCT добавит лишь ненужную нагрузку на СУБД.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ