Как сгруппировать строки SQL по двум столбцам
Укажите оба столбца после GROUP BY: каждая уникальная пара значений станет одной группой. Агрегатная функция — например, SUM или AVG — вычислит результат внутри каждой такой группы.
Минимальный набор данных
Если каждая пара ключей встречается один раз, агрегат не объединяет несколько значений. Для наглядности возьмём продажи: две строки относятся к одной паре «регион / товар».
WITH sales(region, product, amount) AS (
VALUES ('East', 'Book', 10),
('East', 'Book', 20),
('West', 'Book', 5)
)
SELECT region, product, SUM(amount) AS total
FROM sales
GROUP BY region, product
ORDER BY region, product;Запрос использует CTE с VALUES и не создаёт постоянных таблиц. Пример рассчитан на PostgreSQL; синтаксис временного набора данных в другой СУБД может отличаться.
| region | product | total |
|---|---|---|
| East | Book | 30 |
| West | Book | 5 |
Как выбрать ключи группировки
Сначала определите, что должна означать одна строка результата. Если нужен итог по региону независимо от товара, группируйте только по region. Если нужен итог по каждому товару в регионе, нужны оба ключа. Добавление уникального идентификатора продажи в GROUP BY снова разделит строки на отдельные группы.
WHERE и HAVING решают разные задачи
WHERE фильтрует исходные строки до группировки. HAVING фильтрует уже сформированные группы. Например, HAVING SUM(amount) > 10 оставит только группу East / Book с итогом 30.
SELECT region, product, SUM(amount) AS total
FROM sales
WHERE amount > 0
GROUP BY region, product
HAVING SUM(amount) > 10
ORDER BY total DESC, region, product;Этот вариант предполагает существование таблицы sales либо такого же CTE перед SELECT. В результирующий SELECT обычно включают ключи группировки и агрегаты; неагрегированные выражения должны соответствовать правилам выбранной СУБД.
Что проверить перед использованием
- Повторяются ли в тестовых данных комбинации ключей: иначе пример не покажет объединения строк.
- Как обрабатываются NULL: COUNT(*) и COUNT(column) дают разные результаты при пустых значениях.
- Нужен ли фиксированный порядок: GROUP BY сам по себе его не обещает, используйте ORDER BY.
- Не появилась ли лишняя кратность после JOIN до группировки: она способна увеличить сумму.