SQL mastery
On this page 8 topics
Overview
Topics
- CTEs
- recursive queries
- window functions
- advanced joins
- set operations
Learn first
5 h of practice (estimate)
Learning outcomes
- Structure complex queries with CTEs and write recursive CTEs for hierarchies.
- Use window functions (
ROW_NUMBER,RANK,LAG, running totals, partitions). - Use set operations, lateral joins, and
FILTERclauses. - Write upserts with
INSERT … ON CONFLICT.
Lessons
Lab and exercises
Lab
MID-011-LAB1 · Analytics queries
Outcomes: 1–4 · Time: ~3 h Using the Shop schema with generated data, write: (a) top 3 products per category per month, (b) customer retention cohorts (first-order month vs months since), (c) the category tree with totals including all descendants. Write a plain Java implementation of each to cross-check. Acceptance: one SQL query per report; results match the Java implementation on the same data.
Exercises (assessment: timed SQL test plus these exercises)
| ID | Outcome | Task |
|---|---|---|
| MID-011-EX01 | 1 | Rewrite a three-level nested subquery as chained CTEs. |
| MID-011-EX02 | 1 | List every descendant of category 5 with its depth using a recursive CTE. |
| MID-011-EX03 | 2 | For each customer, number orders by date and show days since the previous order. |
| MID-011-EX04 | 2 | Explain the difference between ROW_NUMBER, RANK, and DENSE_RANK on tied values 10, 10, 8. |
| MID-011-EX05 | 3 | For each category, get the 2 newest products using LATERAL. |
| MID-011-EX06 | 3 | Produce paid, cancelled, and refunded counts per month in one query with FILTER. |
| MID-011-EX07 | 4 | Write an idempotent upsert for product_stock(product_id, qty) that adds to the quantity. |
Show solutions
- EX01
WITH a AS (...), b AS (SELECT ... FROM a ...), c AS (...) SELECT ... FROM c;each step named. - EX02 Anchor
WHERE id = 5, 0 AS depth; recursive part joinscategory c ON c.parent_id = t.id,depth + 1. - EX03
row_number() OVER (PARTITION BY customer_id ORDER BY created_at)andcreated_at - lag(created_at) OVER (PARTITION BY customer_id ORDER BY created_at). - EX04
ROW_NUMBER1,2,3;RANK1,1,3;DENSE_RANK1,1,2. - EX05
FROM category c CROSS JOIN LATERAL (SELECT ... WHERE category_id = c.id ORDER BY created_at DESC LIMIT 2) p. - EX06
date_trunc('month', created_at)with threecount(*) FILTER (WHERE status = ...)columns, grouped by month. - EX07
INSERT ... VALUES (...) ON CONFLICT (product_id) DO UPDATE SET qty = product_stock.qty + EXCLUDED.qty. - The "window vs GROUP BY" and "aggregate in Java" mistakes are covered by EX03, EX06, and the lab cross-check.
Quiz
Outcomes: O1 CTEs and recursion · O2 window functions · O3 joins, set operations, FILTER · O4 upserts.
A self-check for you: nothing is graded, saved or sent anywhere. Choose an answer, then check it. You can try again as often as you like.
Practical part
Timed SQL test (three queries from the lab's families) plus exercises MID-011-EX01 to EX07 and the lab. Pass: quiz 8/10, the timed test answered correctly, and lab results matching the Java check.
Common mistakes
Pulling rows into Java to aggregate; window functions confused with GROUP BY.
Assessment
Timed SQL test.
Career relevance
Reporting, data platforms (SRB-007).