В SQL часто нужно избавиться от повторяющихся строк: уникальные пользователи, товары, категории. Для этого используют
DISTINCT и GROUP BY. Результат может выглядеть одинаково, но назначение и смысл у этих конструкций разные.Представим таблицу заказов:
orders(id, customer_id, product_id)
Найдём всех уникальных клиентов, которые делали заказы:
SELECT DISTINCT customer_id
FROM orders;
DISTINCT удаляет дубликаты по всему набору выбранных колонок в результирующем наборе — без группировок и агрегаций.Сделаем то же самое через
GROUP BY:SELECT customer_id
FROM orders
GROUP BY customer_id;
Результат будет тем же, но семантически запрос другой: явно группируем строки по
customer_id. В простых случаях оптимизатор часто строит одинаковый план, но логика запроса уже «про группы».GROUP BY становится необходимым, когда появляются агрегаты.Посчитаем количество заказов на каждого клиента:
SELECT customer_id, COUNT(*) AS orders_count
FROM orders
GROUP BY customer_id;
В этом запросе
GROUP BY обязателен, потому что мы одновременно выбираем агрегат (COUNT(*)) и неагрегированное поле (customer_id).Частая ошибка — смешивать
DISTINCT и агрегаты без GROUP BY:SELECT DISTINCT customer_id, COUNT(*)
FROM orders;
Такой запрос в стандартном SQL некорректен: неагрегированные поля должны присутствовать в
GROUP BY. В зависимости от СУБД и режима он либо не выполнится, либо вернёт неопределённый результат.Корректный вариант:
SELECT customer_id, COUNT(*) AS orders_count
FROM orders
GROUP BY customer_id;
🔥 Используй
DISTINCT для простого удаления дублей, а GROUP BY — когда нужна агрегация, расчёты по группам или HAVING.➡️ SQL Ready | #практика