Every prior file in this module taught one concept in isolation. Real reporting work never asks for just one — it asks for a full KPI report combining several aggregates at once, across a real business domain. This file closes the module by walking through complete, realistic reporting scenarios end to end.
COUNT, SUM, AVG, MIN, MAX, GROUP BY, HAVING, and conditional aggregation in single, realistic queriesA single well-formed business report query typically layers:
SELECT <grouping column(s)>, <aggregate 1>, <aggregate 2>, ...
FROM <base table>
JOIN <related tables as needed>
WHERE <row-level filters, applied before grouping>
GROUP BY <grouping column(s)>
HAVING <group-level filters, applied after aggregation>
ORDER BY <most useful sort for the audience>
This file works through that shape across five business domains, using the schema already established in this module.
Same as the rest of the module: employes(emp_id, emp_name, dept_id, manager_id, salary), departments(dept_id, dept_name, location_id), locations(location_id, city).
Business question: “For each department with more than one employee, show headcount, average salary, salary range, and the split between employees earning above and below $50,000 — sorted by headcount, largest first.”
This single question requires COUNT, AVG, MIN, MAX, GROUP BY, HAVING, and conditional aggregation together — see 08_BUSINESS_CASES.sql Q1 for the full query.
Business question: “How many employees work in each city, and what’s the average salary there? Only show cities with at least 2 employees, since smaller sites don’t need a dedicated facilities review.”
This is the canonical “3-table join + GROUP BY + HAVING” pattern established across the module, now applied as a real deliverable. See 08_BUSINESS_CASES.sql Q2.
Business question: “Which departments have a pay-band spread (max minus min salary) greater than $15,000? This might indicate inconsistent role scoping that needs review before the next compensation cycle.”
See 08_BUSINESS_CASES.sql Q3 — this reuses the MAX() - MIN() derived-aggregate pattern from 04_MIN_MAX.sql, filtered with HAVING.
Business question: “Which managers have more than one direct report, and what’s the average salary of their team?”
See 08_BUSINESS_CASES.sql Q4 — this reuses the multi-column GROUP BY dept_id, manager_id pattern from 05_GROUP_BY.sql, generalized to span-of-control analysis.
Business question: “Give me one row: total headcount, total payroll, average salary, and the highest single salary in the company — for the executive dashboard header.”
See 08_BUSINESS_CASES.sql Q5 — a no-GROUP BY query, the entire table treated as one implicit group, demonstrating that everything learned in this module works even without an explicit grouping column.
HAVING clause in disguise; “only for Nagpur” is a WHERE clause in disguise. Translating business language into the row-filter-vs-group-filter distinction is the actual skill this module builds.COUNT(*) alongside averages so the reader can judge how much weight to give each row (a department average over 1 person carries far less signal than one over 50).SELECT ... FROM ... JOIN skeleton and confirm the row-level data looks right before adding GROUP BY. Debugging a wrong aggregate on top of a wrong join is much harder than debugging either alone.avg_department_salary), never leave it as the literal function call in output meant for a report or API response.HAVING threshold is a business rule (e.g., “$50,000”, “more than 1 employee”), treat it as a parameter, not a hardcoded literal, the moment this query leaves an exploratory notebook and enters production code.COUNT(*) alongside AVG() even if the business only asked for the average?Real reporting work is rarely a single aggregate function in isolation — it’s COUNT, SUM, AVG, MIN/MAX, GROUP BY, HAVING, and conditional aggregation composed together to answer one specific business question. This file is the bridge between “I know what SUM() does” and “I can write the query behind an actual dashboard.”
08_BUSINESS_CASES.sql Q1.Related Topics: GROUP BY · HAVING · Conditional Aggregation
| ← Previous Lesson | ↑ Module README | Next Module → |