AI InterviewSearch…Search problems, topics, or pages…Ctrl KGet started
Skip to content

06 Aggregation / Checkpoint

Checkpoint — Aggregation

25 min · +25 XP · 3 exercises · 12 questions

Exercises0/3
Quiz · 70% to clear12 q

This checkpoint covers the whole module: the aggregate functions and how they treat NULL and empty input; GROUP BY on columns and expressions; HAVING and how it differs from WHERE; conditional aggregation with SUM(CASE …) for counts, pivots and rates; GROUP_CONCAT with DISTINCT, ORDER BY and SEPARATOR; and the grouping mistakes — ONLY_FULL_GROUP_BY, the three COUNTs, and averages of averages.

How it works. Twelve questions and three queries. You need 70% on the questions and every query accepted to clear the module. You can retake it as often as you like; your best score counts.

Before you start, make sure you can answer these from memory:

  • What do COUNT(*), COUNT(col) and COUNT(DISTINCT col) each count?
  • What do SUM and COUNT return when no rows match?
  • What may appear in the SELECT list of a grouped query, and what does error 1055 mean?
  • In what order do WHERE, GROUP BY, HAVING, SELECT and ORDER BY run?
  • How do you find values that appear more than once in a column?
  • Why does COUNT(CASE WHEN … THEN 1 ELSE 0 END) count every row?
  • Where do DISTINCT, ORDER BY and SEPARATOR go in a GROUP_CONCAT call?
  • Why is an average of averages usually wrong, and what do you compute instead?

The three queries are a monthly sales summary with a revenue floor, a transaction report with approved counts and amounts per month and country, and a daily product list with distinct counts and sorted names.

Common questions

What is the difference between COUNT(*) and COUNT(col)?

COUNT(*) counts rows, whatever they contain; COUNT(col) counts only the rows where col is not NULL. COUNT(DISTINCT col) goes further and counts the different non-NULL values. Say which noun you are counting before choosing one.

When does a condition go in WHERE and when in HAVING?

A condition on individual rows that needs no aggregate goes in WHERE, which runs before grouping and reduces the work. A condition on a group, using COUNT, SUM, MIN or another aggregate, can only go in HAVING, which runs after grouping.

How do you count several statuses per group in one query?

Use one conditional aggregate per status, such as SUM(CASE WHEN status = 'paid' THEN 1 ELSE 0 END) AS paid, side by side in the SELECT list with a GROUP BY on the row label. Every group stays in the result, and a status with no rows shows 0.

SQL GROUP BY Quiz: Aggregates, HAVING and Pivot Practice Test

Test yourself: 12 questions and three queries on COUNT, SUM and AVG with NULLs, GROUP BY, HAVING, conditional aggregation, group concat and grouping mistakes.

  • Course: SQL study plan
  • Module: Aggregation
  • Kind: Checkpoint — cleared at 70%
  • Reading time: 25 min
  • Runtime: MySQL 8 syntax on SQLite 3.49

Checkpoint — Aggregation is the checkpoint that closes the Aggregation module: a graded quiz and whole-program exercises, passed at 70%.

Instructions

This checkpoint covers the whole module: the aggregate functions and how they treat NULL and empty input; GROUP BY on columns and expressions; HAVING and how it differs from WHERE; conditional aggregation with SUM(CASE …) for counts, pivots and rates; GROUP_CONCAT with DISTINCT, ORDER BY and SEPARATOR; and the grouping mistakes — ONLY_FULL_GROUP_BY, the three COUNTs, and averages of averages.

How it works. Twelve questions and three queries. You need 70% on the questions and every query accepted to clear the module. You can retake it as often as you like; your best score counts.

Before you start, make sure you can answer these from memory:

  • What do COUNT(*), COUNT(col) and COUNT(DISTINCT col) each count?
  • What do SUM and COUNT return when no rows match?
  • What may appear in the SELECT list of a grouped query, and what does error 1055 mean?
  • In what order do WHERE, GROUP BY, HAVING, SELECT and ORDER BY run?
  • How do you find values that appear more than once in a column?
  • Why does COUNT(CASE WHEN … THEN 1 ELSE 0 END) count every row?
  • Where do DISTINCT, ORDER BY and SEPARATOR go in a GROUP_CONCAT call?
  • Why is an average of averages usually wrong, and what do you compute instead?

The three queries are a monthly sales summary with a revenue floor, a transaction report with approved counts and amounts per month and country, and a daily product list with distinct counts and sorted names.

Common questions

What is the difference between COUNT(*) and COUNT(col)?

COUNT(*) counts rows, whatever they contain; COUNT(col) counts only the rows where col is not NULL. COUNT(DISTINCT col) goes further and counts the different non-NULL values. Say which noun you are counting before choosing one.

When does a condition go in WHERE and when in HAVING?

A condition on individual rows that needs no aggregate goes in WHERE, which runs before grouping and reduces the work. A condition on a group, using COUNT, SUM, MIN or another aggregate, can only go in HAVING, which runs after grouping.

How do you count several statuses per group in one query?

Use one conditional aggregate per status, such as SUM(CASE WHEN status = 'paid' THEN 1 ELSE 0 END) AS paid, side by side in the SELECT list with a GROUP BY on the row label. Every group stays in the result, and a status with no rows shows 0.

Exercises

Monthly sales with a revenue floor

Summarise sales per month, leaving out rows from the test region (a NULL region is a real sale and counts), and keep only months whose revenue is at least 100.

idsold_onamountregion
12024-01-0440north
22024-01-1870south
32024-01-20500test
42024-02-0230north
52024-02-1050north
62024-03-05120south
72024-03-2515north
82024-02-12900test

Return month (2024-01), sales, revenue, avg_sale (rounded to 2 decimals) and biggest. Order by month.

month | sales | revenue | avg_sale | biggest
2024-01 | 2 | 110 | 55 | 70
2024-03 | 2 | 135 | 67.5 | 120

Monthly transactions report

For each month and country, report the transactions and the approved ones.

idcountrystateamounttrans_date
121USapproved10002018-12-18
122USdeclined20002018-12-19
123USapproved20002019-01-01
124DEapproved20002019-01-07

Return month (2018-12), country, trans_count, approved_count, trans_total_amount and approved_total_amount (0 when nothing was approved). country may be NULL; those rows form their own group. Order by month, then country.

month | country | trans_count | approved_count | trans_total_amount | approved_total_amount
2018-12 | US | 2 | 1 | 3000 | 1000
2019-01 | DE | 1 | 1 | 2000 | 2000
2019-01 | US | 1 | 1 | 2000 | 2000

Busy days and what sold

From orders, list the days on which at least two different customers ordered.

order_datecustomerproduct
2024-04-01anapen
2024-04-01rajink
2024-04-01anaink
2024-04-02rajpad
2024-04-02rajpen
2024-04-03lipen
2024-04-03anapad
2024-04-03rajpad

Return order_date, customers (different customers that day) and products (the different products, alphabetical, separated by , ). Order by order_date.

order_date | customers | products
2024-04-01 | 2 | ink, pen
2024-04-03 | 3 | pad, pen

In this module: Aggregation

← Grouping pitfalls — ONLY_FULL_GROUP_BY, COUNT and averages · INNER JOIN — matching rows across tables →