Группы по нескольким столбцам
В GROUP BY можно указать несколько столбцов через запятую. Тогда строки попадают в одну группу, только если у них одинаковые значения во всех этих столбцах. Сколько игр каждого жанра для каждого возраста?
SELECT genre, age_rating, COUNT(*) AS game_count
FROM games
GROUP BY genre, age_rating
ORDER BY genre, age_rating;| genre | age_rating | game_count |
|---|---|---|
| Action | 12 | 1 |
| Action | 16 | 2 |
| Action | 18 | 1 |
| Adventure | 7 | 1 |
| Adventure | 12 | 2 |
| … | … | … |
Четыре игры жанра Action разделились: две для возраста 16+ (Shadow Ninja и Robot Rebellion), одна для 12+ и одна для 18+. В результате по одной строке на каждое сочетание жанра и возраста, которое есть в таблице. Сочетаний, в которых нет ни одной игры, например игр жанра Action для трёхлетних, в результате нет.
Правило из предыдущих упражнений остаётся в силе: каждый столбец в SELECT, который не находится внутри агрегатной функции, должен входить в GROUP BY. Здесь это и genre, и age_rating.
Группировать можно и по выражению, например по функции. С помощью strftime('%Y', …) из урока о функциях можно получить количество клиентов, зарегистрировавшихся в каждом году:
SELECT strftime('%Y', joined) AS year, COUNT(*) AS new_customers
FROM customers
GROUP BY strftime('%Y', joined)
ORDER BY year;| year | new_customers |
|---|---|
| 2023 | 5 |
| 2024 | 5 |
| 2025 | 4 |
В GROUP BY пишите то же выражение, что и в SELECT. И его тоже можно сочетать со столбцами: GROUP BY strftime('%Y', joined), city посчитал бы новых клиентов каждого города в каждом году.
Типичная ошибка: пропустить столбец в GROUP BY. В результате SELECT genre, age_rating, COUNT(*) FROM games GROUP BY genre; по одной строке на каждый жанр, а его age_rating — это возраст одной из игр жанра, как вы видели с названиями два упражнения назад.
Задание
- 1
Сколько отзывов с каждым числом звёзд получила каждая игра? Покажите
game_id,starsи количество отзывов в столбцеreview_count, отсортировав поgame_id, а затем поstars:game_id stars review_count 1 3 1 1 4 1 1 5 2 2 2 1 … … … - 2
Ниже посчитайте заказы каждого года с каждым статусом: год (
strftime('%Y', ordered_at)) в столбцеyear, затемstatusи количество заказов в столбцеorder_count, отсортировав по году и статусу:year status order_count 2024 paid 14 2024 refunded 1 2025 paid 14 2025 refunded 1