SQL-Engineering-Handbook

Module 02 β€” Aggregations

πŸ“š Module Navigation

Lesson Topic Open
01 COUNT() 01_COUNT.md
02 SUM() 02_SUM.md
03 AVG() 03_AVG.md
04 MIN() & MAX() 04_MIN_MAX.md
05 GROUP BY 05_GROUP_BY.md
06 HAVING 06_HAVING.md
07 Conditional Aggregation 07_CONDITIONAL_AGGREGATION.md
08 Business Cases 08_BUSINESS_CASES.md

Module 02 β€” Aggregations

Introduction

Aggregation is where SQL stops answering β€œwhat are the rows” and starts answering β€œwhat do the rows mean.” Every dashboard tile, every KPI, every executive summary in every company that uses a relational database is, underneath, an aggregation query. This module builds that skill from COUNT(*) up to full multi-clause business reports.

Why Aggregations Matter

Raw rows are not insight. β€œHere are 50,000 order records” tells a business nothing actionable. β€œTotal revenue this month is $2.4M, up 12% from last month, driven mainly by the Nagpur region” β€” that sentence is entirely the output of SUM, GROUP BY, and comparison logic. Aggregation is the layer that turns data into decisions.

Business Motivation

Every function in this module maps directly to a question a real business asks daily:

Business Question SQL Concept
β€œHow many customers do we have?” COUNT()
β€œWhat’s our total revenue?” SUM()
β€œWhat’s our average order value?” AVG()
β€œWhat was our biggest sale? Our smallest?” MIN() / MAX()
β€œBreak that down by region.” GROUP BY
β€œOnly show regions above $1M.” HAVING
β€œShow active vs. inactive counts side by side.” Conditional Aggregation

Learning Objectives

By the end of this module, you will be able to:

Prerequisites

Completion of Module 01 β€” Fundamentals (SELECT, WHERE, ORDER BY, JOIN basics) and familiarity with the module’s schema (below). No prior aggregation knowledge assumed.

Module Structure

# File Covers
01 COUNT() Row counting, DISTINCT, NULL behavior
02 SUM() Totals, NULL handling, empty-group behavior
03 AVG() Means, the β€œaverage of averages” trap
04 MIN() & MAX() Extremes across numeric/date/text
05 GROUP BY Per-category aggregation, the GROUP BY rule
06 HAVING Group-level filtering, WHERE vs. HAVING
07 Conditional Aggregation CASE WHEN inside aggregates, FILTER
08 Business Cases Full multi-clause reports across 5 domains

Each .md file has a matching .sql file with fully worked, business-scenario queries, expected output, and engineering notes.

Functions Covered

COUNT() Β· COUNT(DISTINCT) Β· SUM() Β· AVG() Β· MIN() Β· MAX() Β· GROUP BY (single- and multi-column) Β· HAVING Β· CASE WHEN inside aggregates Β· PostgreSQL FILTER (WHERE ...)

Schema Used Throughout This Module

employes                    departments               locations
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ emp_id (PK) β”‚             β”‚ dept_id (PK)β”‚           β”‚ location_id  β”‚
β”‚ emp_name    β”‚             β”‚ dept_name   β”‚           β”‚      (PK)    β”‚
β”‚ dept_id (FK)│────────────▢│ location_id │──────────▢│ city         β”‚
β”‚ manager_id  β”‚             β”‚      (FK)   β”‚           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ salary      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

(Note: the employes spelling is used consistently across this repository’s seed data and is preserved here rather than β€œcorrected,” to avoid breaking cross-references to existing queries.)

Learning Roadmap

COUNT ──▢ SUM ──▢ AVG ──▢ MIN/MAX ──▢ GROUP BY ──▢ HAVING ──▢ Conditional Aggregation ──▢ Business Cases
  β”‚                                        β”‚                                                    β”‚
  └── single-value aggregates β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                                    β”‚
                                  per-category aggregates + filtering                            β”‚
                                                                              full realistic reports

Aggregation Pipeline (Execution Order)

This is the single most important diagram in the module β€” internalize it before moving on:

FROM   β†’ the base table(s) and JOINs
WHERE  β†’ filter individual ROWS (before any grouping happens)
GROUP BY β†’ collapse rows into per-category groups
HAVING β†’ filter GROUPS, based on aggregated values
SELECT β†’ compute and return final columns
ORDER BY β†’ sort the final result set

A condition on a raw column (dept_id = 10) belongs in WHERE. A condition on an aggregate result (COUNT(*) > 5) belongs in HAVING. Mixing these up is the most common aggregation bug in production SQL.

Business Domains Covered

HR (headcount, payroll) Β· Workforce Planning (city/site capacity) Β· Compensation (pay-band analysis) Β· Org Design (manager span of control) Β· Executive Reporting (single-row KPI summaries) β€” see 08_BUSINESS_CASES.md for full worked examples in each.

Engineering Workflow

  1. Confirm the base SELECT ... FROM ... JOIN returns the correct rows before adding any aggregate function.
  2. Decide what one output row should represent (e.g. β€œone row per department”) β€” this determines your GROUP BY columns.
  3. Add aggregates to the SELECT list, aliasing every one with a business-meaningful name.
  4. Add WHERE for row-level filters, HAVING for group-level filters β€” never mix the two up.
  5. ORDER BY for the audience reading the output.

Performance Considerations

Common Mistakes (Module-Wide)

Best Practices

Interview Preparation

This module’s .md files each end with a targeted interview-question set. The three most frequently asked aggregation interview questions, module-wide:

  1. β€œWhat’s the difference between WHERE and HAVING?” β€” Covered in depth in 06_HAVING.md.
  2. β€œWhy does COUNT(*) return 0 on an empty table, but SUM() returns NULL?” β€” Covered in 01_COUNT.md and 02_SUM.md.
  3. β€œHow would you get counts for two different conditions in one query row?” β€” Covered in 07_CONDITIONAL_AGGREGATION.md.

Career Relevance

Aggregation queries are asked in nearly every SQL technical screen, regardless of company or seniority level, because they test both syntax knowledge and the ability to translate a business question into precise, correctly-ordered SQL clauses β€” exactly the skill this module is built around.

Estimated Time

4–6 hours for a first pass through all 8 files, including practice challenges.

Difficulty

Beginner β†’ Intermediate (Files 01–06: Beginner. Files 07–08: Intermediate, and the natural bridge into Module 12’s advanced aggregation techniques.)

Previous Module

β—€ Module 01 β€” Fundamentals

Next Module

Module 03 β€” Joins β–Ά

(Also see Module 12 β€” Advanced Aggregations for ROLLUP, CUBE, and GROUPING SETS, which build directly on the GROUP BY/HAVING foundation from this module, and Module 11 β€” NULL Handling and Data Cleaning for a deeper treatment of NULL beyond the aggregate-specific behavior covered here.)

Visual Learning

Every diagram used across this module’s lessons, in one place:

Diagram Used In
COUNT variants 01_COUNT.md
SUM NULL handling 02_SUM.md
AVG denominator 03_AVG.md
MIN/MAX across types 04_MIN_MAX.md
GROUP BY bucketing 05_GROUP_BY.md
WHERE vs HAVING flow 06_HAVING.md
CASE WHEN pivot 07_CONDITIONAL_AGGREGATION.md
Business case query anatomy 08_BUSINESS_CASES.md

Further Reading