SQL Practice
SQL is the analyst's working language: you pull, aggregate, and filter data in it before you ever open a BI tool or Python. In interviews the first tasks are almost always exactly this — "count", "group", "find those with more than N". Behind the apparent simplicity hide traps: an aggregate in WHERE, losing rows that share the maximum, grouping at the wrong granularity.
This topic covers the two bricks the whole of analytical SQL rests on: aggregate functions that collapse many rows into one number, and the GROUP BY + HAVING pair that does the same per group. Get clear on the order in which the database runs WHERE, GROUP BY, and HAVING, and most traps vanish on their own. Details in the layers below.
Topic map
- Aggregate functions —
COUNT,SUM,AVG,MIN,MAX, collapsing rows into one value, and the trap of dropping ties. - Grouping and HAVING —
GROUP BYat the right granularity and theHAVINGfilter that can reference an aggregate, unlikeWHERE.
Common traps
| Mistake | Consequence |
|---|---|
Putting an aggregate in WHERE (WHERE COUNT(...) > 1) | Query error — WHERE runs before aggregation and cannot see COUNT() |
SELECT MAX(salary), first_name with no GROUP BY | Error or an arbitrary row — a plain column beside an aggregate without grouping is invalid |
ORDER BY salary DESC LIMIT 1 for "the maximum" | Employees tied at the maximum are lost |
| Grouping at the wrong granularity | "More than one order per day" becomes "per month" if you forget the day in GROUP BY |
| Confusing "above average" with "the maximum" | WHERE salary > AVG(...) returns half the table, not the top |
Interview relevance
Analytical SQL is tested as basic literacy: can you think in "sets of rows" rather than row by row. A candidate who says the execution order aloud — "first WHERE on rows, then GROUP BY, then aggregates, then HAVING on groups" — immediately looks more convincing than one who shuffles conditions between WHERE and HAVING at random.
Typical checks:
- Whether you know an aggregate is computed over a group of rows, and why a plain column cannot be mixed with
MAX()withoutGROUP BY. - Where an aggregate filter goes — in
HAVING, notWHERE, and why. - How to keep every row tied at the maximum instead of
LIMIT 1. - How to choose the grouping granularity to fit the task's wording.
Common wrong answer: "I'll put COUNT() > 1 in WHERE". WHERE runs before grouping and the aggregate does not exist yet — a count condition lives only in HAVING.