Tutorials, performance tips, interview guides, and database deep-dives — written to make SQL click.
SQL doesn't run in the order you write it. The real logical order — and why you can't filter on a SELECT alias.
Row filter, group filter, or projection? What each clause really does — with real, side-by-side SQL.
Venn diagrams, sample tables, and the exact rows each join returns — plus the classic LEFT-JOIN gotcha.
Seven GROUP BY traps — from non-grouped columns to join fan-out — each with a clear fix and example.
One counts rows, one skips NULLs, one counts unique values — proven on a single dataset. Plus the COUNT(1) myth.
Why = NULL never works, three-valued logic, the NOT IN trap,
and COALESCE — with fixes.
Short answer: after — always. Why, plus exactly what you can sort by once you've grouped.
A 60-second debugging checklist: NULL logic, join fan-out, integer division, precedence, and more.
OVER(), PARTITION BY, and running totals — window functions demystified with the simplest possible examples, no jargon required.
Three ranking functions that look similar and behave very differently with ties. Which one to reach for, with side-by-side output.
Same job, different tools. When a CTE makes a query more readable — and when a subquery is actually the better call.
The subquery that references its outer query, row by row. How they work, why they're slow, and when they're worth it.
Walking a hierarchy — org charts, category trees, and bill-of-materials — with WITH RECURSIVE, explained from the ground up.
ROLLUP, CUBE, GROUPING SETS, and conditional aggregation — GROUP BY tricks that go well beyond the basics.
What actually happens between your query and its results: statistics, execution plans, and why two "equivalent" queries can run at very different speeds.
Six root causes behind almost every slow query — missing indexes, bad predicates, SELECT *, and more — with before/after timing.
B-trees, single-column, composite, and covering indexes — how each one actually works, with real query timing.
What each scan type does physically, and the selectivity math that decides which one the optimizer picks.
Five situations where adding an index makes performance worse, not better — with real INSERT timing before and after.
From your first EXPLAIN ANALYZE to cost numbers, join algorithms, and spotting a bad row estimate.
Diagnose, rewrite, index, verify, monitor — the exact order that actually works, with a full before/after example.
Seven mistakes that pass code review but quietly wreck performance — each with a fix and before/after timing.
You can't filter on a total that doesn't exist yet — the logical reason HAVING comes after GROUP BY, and how it differs from WHERE.
GROUP BY doesn't need COUNT() or SUM() — at its core it's a deduplication tool. How it compares to DISTINCT.
Why WHERE can't see a SELECT alias but ORDER BY can — and how GROUP BY, HAVING, and table aliases scope differently.
Eight classic traps — NULL comparisons, second-highest salary, UNION vs UNION ALL — with wrong vs correct output tables.
Given this table and this query — what comes out? Six predict-the-output questions with wrong vs correct results.
Cartesian products, self-joins, and join fan-out — six join questions with wrong vs correct output tables.
Simple vs searched CASE, pivoting with conditional aggregation, and the missing-ELSE trap — with output tables.
ROW_NUMBER vs RANK vs DENSE_RANK with ties, running totals, and LAG/LEAD — with output tables.
The ungrouped column error, WHERE vs HAVING order, and finding duplicates — with wrong vs correct output tables.
Correlated vs non-correlated, IN vs EXISTS, and the NOT IN with NULL trap — with output tables.
It's rarely the syntax — join fan-out, NULL assumptions, and not narrating your reasoning out loud.
New articles are on the way.