Группы с GROUP BY
Сколько игр каждого жанра в магазине? С тем, что вы знаете сейчас, понадобился бы запрос на каждый жанр: WHERE genre = 'Action', WHERE genre = 'Adventure' и так далее, восемь раз. GROUP BY делает это одним запросом:
SELECT genre, COUNT(*) AS game_count
FROM games
GROUP BY genre
ORDER BY genre;| genre | game_count |
|---|---|
| Action | 4 |
| Adventure | 3 |
| Puzzle | 2 |
| RPG | 2 |
| Racing | 2 |
| Simulation | 2 |
| Sports | 2 |
| Strategy | 3 |
GROUP BY genre разбивает строки на группы: все строки с одинаковым жанром попадают в одну группу. Четыре игры жанра Action (Shadow Ninja, Star Pilots, Zombie Town и Robot Rebellion) образуют одну группу, три игры жанра Adventure — другую, и так далее. Затем агрегатная функция работает с каждой группой отдельно, и в результате по одной строке на каждую группу: жанр и количество его игр.
Так работает каждая агрегатная функция, и можно использовать несколько сразу:
SELECT genre, MIN(price) AS cheapest, MAX(price) AS most_expensive
FROM games
GROUP BY genre
ORDER BY genre;| genre | cheapest | most_expensive |
|---|---|---|
| Action | 25 | 40 |
| Adventure | 15 | 25 |
| Puzzle | 5 | 10 |
| … | … | … |
GROUP BY идёт после FROM и WHERE и перед ORDER BY. Группы могут прийти отсортированными, но ничто этого не гарантирует, поэтому, когда порядок важен, добавляйте ORDER BY. Строки, в которых в столбце NULL, образуют отдельную группу.
Что может стоять в SELECT рядом с агрегатной функцией? Столбцы, по которым вы группируете, потому что во всей группе они одинаковы, и агрегатные функции, которые вычисляют из группы одно значение. Больше ничего: в группе много строк с разными названиями, так какое из них показать в результате?
Типичная ошибка: столбец, которого нет в GROUP BY. Большинство баз данных сообщают об ошибке, что столбец должен входить в GROUP BY или использоваться в агрегатной функции. SQLite — нет; он берёт название из одной из строк каждой группы:
SELECT genre, title, COUNT(*) AS game_count
FROM games
GROUP BY genre;| genre | title | game_count |
|---|---|---|
| Action | Shadow Ninja | 4 |
| Adventure | Lost Temple | 3 |
| … | … | … |
Теперь в каждой строке название одной игры стоит рядом с количеством игр всего жанра, и это бессмысленно. Когда видите такой результат, проверьте, что каждый столбец в SELECT либо входит в GROUP BY, либо находится внутри агрегатной функции.
Задание
- 1
Посчитайте клиентов в каждом городе: покажите город и количество его клиентов в столбце
customer_count, отсортировав по городу. Клиенты без города тоже образуют группу:city customer_count NULL 2 Bristol 3 Leeds 2 London 4 Manchester 3 - 2
Ниже вычислите сумму каждого заказа из
order_items: номер заказа (order_id) и суммуquantity * priceв столбцеorder_total, отсортировав поorder_id:order_id order_total 1 25 2 35 3 40 4 40 5 65 6 30 … …