← Learning Hub
SQLFREE IN BOTH LANGUAGESLesson 04 / 12

GROUP BY & JOIN

Summarize categories and connect related tables without inflating totals.

Download notes (.md)

Downloads are text notes. Choose Save as PDF in your browser’s print dialog for a PDF copy.

Understand the concept

GROUP BY gathers rows with the same key so an aggregate such as COUNT or SUM can summarize each group. WHERE filters rows before grouping; HAVING filters the grouped results. COUNT(*) counts rows, while COUNT(column) excludes NULL values in that column.

JOIN connects rows through a matching condition. INNER JOIN keeps matching rows; LEFT JOIN also keeps every left-side row and fills unmatched right-side fields with NULL. A one-to-many relationship intentionally produces multiple rows for one key.

Check the grain: what does one row mean before and after a join? Joining two tables with multiple matches per key can multiply rows and inflate sums. Validate row counts and keys. The runnable SQLite example counts orders per customer, including a customer with no orders.

Run the example

import sqlite3
db = sqlite3.connect(":memory:")
db.executescript("""
CREATE TABLE customers (id INTEGER PRIMARY KEY, name TEXT);
CREATE TABLE orders (id INTEGER PRIMARY KEY, customer_id INTEGER);
INSERT INTO customers VALUES (1, 'Asha'), (2, 'Ravi');
INSERT INTO orders VALUES (10, 1), (11, 1);
""")
print(db.execute("""
SELECT c.name, COUNT(o.id) AS order_count
FROM customers AS c LEFT JOIN orders AS o ON c.id = o.customer_id
GROUP BY c.id, c.name ORDER BY c.id
""").fetchall())
db.close()

Output / what to expect

[('Asha', 2), ('Ravi', 0)]

Try it yourself

Modify the query to keep only customers with at least two orders. Why should you count o.id rather than COUNT(*)?

View a suggested solution
SELECT c.name, COUNT(o.id) AS order_count
FROM customers AS c LEFT JOIN orders AS o ON c.id = o.customer_id
GROUP BY c.id, c.name
HAVING COUNT(o.id) >= 2
ORDER BY c.id;
-- Asha, 2
-- COUNT(o.id) ignores the NULL from an unmatched order.
-- COUNT(*) would count Ravi's preserved left-side row as 1.

Reference: Official documentation ↗

Make it yours.

Run the example and attempt the exercise before marking this lesson complete.

pass the idea on

What did this make you think?

You review and publish the post yourself. Instagram uses your device’s share menu when available; otherwise copy the text and link. Facebook opens the link composer, where you add your thoughts.