GROUP BY & HAVING
Aggregate by groups — and filter those groups
📖 Concept Recap
- GROUP BY column — groups rows with the same value, then aggregates each group
- Every column in SELECT must either appear in GROUP BY or be inside an aggregate function
- HAVING — filters groups after aggregation (like WHERE but for groups)
- WHERE filters rows before grouping; HAVING filters groups after aggregating
Full clause order: SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT
👀 Worked Example
Exercise 1 — Customers with Multiple Orders
Fill in the blanks to find customers who have placed more than 1 order.
customer_id, HAVING COUNT(*) > 1Exercise 2 — Category Sales Volume
Find all product categories where the total quantity sold (sum of quantity from orders joined with products) is greater than 3. Show: category, total quantity sold, total revenue. You’ll need to JOIN orders and products.
Exercise 3 — Power Customers
Write a query that finds “power customers” — customers who have spent more than $500 total. Show: customer_id, number of orders, total spent, and average order value. Order by total spent descending.
Mini Project — Sales Performance Report
Build a complete sales performance report using GROUP BY and HAVING:
- Revenue by customer — all customers with their order count and total revenue
- High-value customers — only those who spent more than $300 total
- Product sales by category — category, number of products in category, times ordered, total revenue
- Monthly revenue trend — grouped by month (use substr), only months with total revenue over $500
✅ Lab 5 Complete!
GROUP BY and HAVING unlock true analytical power. You can now segment any dataset and filter by group-level conditions. Up next: JOINs — the most powerful concept in SQL.