Don't read the cheatsheet — quiz yourself on it. Go to the Flashcard tab and flip through all 15 patterns. For each card:
Goal: zero misses on 3 consecutive passes.
Use the Quick-Fire Drill tab. You see a trigger phrase, you pick the SQL tool in under 3 seconds — no thinking, just reflex. This trains the interviewer → you step: they say "top N per group", your hand is already typing ROW_NUMBER() OVER (PARTITION BY...).
Target: ≥80% accuracy before moving on.
Open a blank editor. Write each skeleton without looking — just from the pattern name. Check against the Cheatsheet tab after each one. The act of retrieving beats re-reading every time.
The enemy is forgetting. Beat it with 15-minute daily sessions:
When they ask a question, say this script out loud:
Click a card to reveal the answer. Mark yourself honestly.
See the trigger phrase → pick the SQL tool. Train your reflexes.
All 15 patterns at a glance. Reference while you practice.
"So I need one row per [X], showing [metric], filtered to [condition]."
"I need orders joined to users. Because I want users with NO refund — that's a LEFT JOIN."
"This is an anti-join pattern" or "This needs ROW_NUMBER() OVER (PARTITION BY user)"
Write WITH / SELECT / FROM / WHERE / GROUP BY / HAVING stubs. Then populate column names.
"I'm using COALESCE here because refund_amount could be NULL. Also NULLIF to avoid divide-by-zero."
| Trigger Phrase | SQL Tool | Skeleton Tip |
|---|
| Edge Case | How to Handle |
|---|---|
| end_date NULL | Means "still active". end_date IS NULL OR end_date >= :date |
| Missing JOIN value | COALESCE(r.amount, 0) — LEFT JOIN right-side cols will be NULL |
| Divide by zero (CTR) | NULLIF(denominator, 0) → 1.0 * num / NULLIF(denom, 0) |
| COUNT(*) vs COUNT(col) | COUNT(*) counts all rows; COUNT(col) skips NULLs |
| Duplicates in source | Use ROW_NUMBER()=1 or DISTINCT before aggregating |
| Timezone (yesterday UTC) | DATE(CONVERT_TZ(ts,'local','UTC')) or AT TIME ZONE |
| SCD effective_end NULL | Current record → COALESCE(effective_end, '9999-12-31') |