Groups with GROUP BY

How many games of each genre does the shop have? With what you know so far, you'd need a query for each genre: WHERE genre = 'Action', WHERE genre = 'Adventure', and so on, eight times. GROUP BY does it in one query:

SELECT genre, COUNT(*) AS game_count
FROM games
GROUP BY genre
ORDER BY genre;
genregame_count
Action4
Adventure3
Puzzle2
RPG2
Racing2
Simulation2
Sports2
Strategy3

GROUP BY genre splits the rows into groups: all the rows with the same genre go into one group. The four action games (Shadow Ninja, Star Pilots, Zombie Town and Robot Rebellion) make one group, the three adventure games another, and so on. The aggregate function then works on each group separately, and the result has one row for each group: the genre and the number of its games.

Every aggregate function works this way, and you can use several at once:

SELECT genre, MIN(price) AS cheapest, MAX(price) AS most_expensive
FROM games
GROUP BY genre
ORDER BY genre;
genrecheapestmost_expensive
Action2540
Adventure1525
Puzzle510
………

GROUP BY comes after FROM and WHERE, and before ORDER BY. The groups may come sorted, but nothing guarantees it, so when the order matters, add ORDER BY. Rows that have NULL in the column form a group of their own.

What can stand in SELECT next to an aggregate function? The columns you group by, because they're the same in the whole group, and aggregate functions, which compute one value from the group. Nothing else: a group has many rows with different titles, so which one should the result show?

Typical mistake: a column that isn't in GROUP BY. Most databases report an error saying that the column must appear in GROUP BY or be used in an aggregate function. SQLite doesn't; it takes the title from one row of each group:

SELECT genre, title, COUNT(*) AS game_count
FROM games
GROUP BY genre;
genretitlegame_count
ActionShadow Ninja4
AdventureLost Temple3
………

Each row now shows the title of one game next to the number of games of the whole genre, which makes no sense. When you see such a result, check that each column in SELECT is either in GROUP BY or inside an aggregate function.

Instructions

Count the customers in each city: show the city and the number of its customers in a column customer_count, sorted by city. The customers without a city make a group too:

citycustomer_count
NULL2
Bristol3
Leeds2
London4
Manchester3

Below it, compute the total of each order from order_items: the ID of the order (order_id) and the sum of quantity * price in a column order_total, sorted by order_id:

order_idorder_total
125
235
340
440
565
630
……

Start programming for free

By signing up, you agree to the Terms of Service and Privacy Policy.

Or sign up with:

5/10