Как вывести уникальные значения по столбцу в SQL
Что проверяют
Знаете ли вы, что DISTINCT относится ко всей выбираемой строке, и понимаете ли разницу с GROUP BY.
Как отвечать
Базовый способ:
select distinct city from users;Тот же результат даёт группировка:
select city from users group by city;Разница в применимости: DISTINCT короче и понятнее, когда нужны просто уникальные значения. GROUP BY нужен, когда рядом требуются агрегаты:
select city, count(*) from users group by city order by count(*) desc;Ключевая тонкость, на которой чаще всего ошибаются: DISTINCT действует на всю строку результата, а не на одну колонку. Запрос select distinct city, name from users вернёт уникальные пары, а не уникальные города. Синтаксиса «уникальность только по одной колонке» в стандарте нет.
Если нужна одна строка на каждое значение, но с дополнительными полями, в PostgreSQL есть расширение:
select distinct on (city) city, name, created_at
from users
order by city, created_at desc;Он вернёт по одной строке на город, выбирая самую свежую. Требование: первые выражения в ORDER BY должны совпадать с указанными в DISTINCT ON.
В переносимом виде ту же задачу решают оконной функцией с нумерацией строк внутри группы и фильтром по номеру.
Что ещё полезно знать:
count(distinct city)считает число уникальных значений;NULLвDISTINCTсчитается одним значением, то есть попадёт в результат один раз;- производительность: уникальность требует сортировки или хеширования всего набора, и на большой таблице это дорого. Индекс по колонке помогает, а если нужно только число уникальных на огромных данных, иногда берут приближённый подсчёт.
Где спотыкаются
Пишут select distinct city, name и ждут уникальные города.
Считают, что DISTINCT можно применить к одной колонке из нескольких.
Не знают про DISTINCT ON и городят подзапросы.
Забывают, что NULL тоже попадёт в результат.