Finished a SQL Course but Can't Solve Problems From Scratch? Here's Why (and a Fix)
You finished a SQL course. You understand joins, CTEs and window functions, and you can follow any solution once you see it. But facing a blank editor, you freeze. This is normal, and it doesn't mean you're on the wrong track. Recognizing a solution and producing one are two different skills. Courses train the first. Only practice trains the second.
Think about learning a language: you can understand a lot of sentences long before you can say them yourself. SQL works the same way. Here's why the gap exists, a step-by-step method for writing queries from scratch, and a practice progression so you stop jumping straight into the deep end.
Why "I Understand It but Can't Write It" Happens
When you read a finished solution, all the hard decisions have already been made: which tables to use, what one row of the output represents, which JOIN, where the filter goes. You're just checking that each step makes sense.
Writing from scratch means making all those decisions yourself, in the right order, with no hints. That's a skill called problem decomposition, and a course full of short exercises that each test one concept doesn't build it much.
Also: if you went from a course straight to Advanced SQL Puzzles, you skipped a few levels. Those puzzles are designed to be hard for people who use SQL professionally. An hour per puzzle is not a bad sign at that level.
A 5-Step Method for Any SQL Problem
Use this every time you sit down with a new problem until it becomes automatic.
Step 1: Decide what one row of the answer means
Before touching any table, finish this sentence: "The result has one row per ____." One row per customer? Per customer per month? Per product category? This single decision tells you what goes in your GROUP BY, or whether you need one at all. Most "my query is wrong" moments come from skipping this step.
Step 2: Sketch the expected output by hand
Write two or three rows of what the answer should look like, with column names. It takes thirty seconds and gives you something to compare against.
-- "Each customer's total spend in 2026, highest first"
customer_name | total_spend
--------------+------------
Ana Ruiz | 1840.00
Ben Cho | 1210.50Step 3: Find the tables and how they connect
Which tables hold the columns you sketched? What are the keys between them? Write the FROM and JOIN lines first, and run them with SELECT * and LIMIT 20. Look at the raw rows. Are there more rows than you expected?
Step 4: Build one clause at a time, running after each
Add the WHERE. Run it. Add the GROUP BY and aggregates. Run it. Add the HAVING or ORDER BY. Run it. If you write a 30-line query and run it once, you can't tell which part broke. If you run it after every clause, the bug is always in the line you just added.
-- Run 1: are the rows what I think?
SELECT * FROM customers c JOIN orders o ON o.customer_id = c.id LIMIT 20;
-- Run 2: add the filter
SELECT * FROM customers c JOIN orders o ON o.customer_id = c.id
WHERE o.order_date >= DATE '2026-01-01' LIMIT 20;
-- Run 3: aggregate to one row per customer
SELECT c.name AS customer_name, SUM(o.amount) AS total_spend
FROM customers c JOIN orders o ON o.customer_id = c.id
WHERE o.order_date >= DATE '2026-01-01'
GROUP BY c.id, c.name
ORDER BY total_spend DESC;Step 5: Break hard problems into CTEs
When a problem feels impossible, it's usually two or three easy problems stacked on top of each other. Solve the first one as a CTE, check it, then build the next step on top of it.
WITH monthly AS ( -- easy problem 1: revenue per month
SELECT DATE_TRUNC('month', order_date) AS month, SUM(amount) AS revenue
FROM orders GROUP BY 1
)
SELECT month, revenue, -- easy problem 2: compare to previous month
revenue - LAG(revenue) OVER (ORDER BY month) AS change
FROM monthly;Hard SQL problems are rarely hard SQL. They're several easy steps where the order isn't obvious yet.
Learn Patterns, Not Just Syntax
Experienced people don't solve every problem from first principles. They recognize which of a dozen standard patterns the problem is. Learning these explicitly is the biggest shortcut there is:
- Anti-join: rows with no match (customers who never ordered)
- Top N per group:
ROW_NUMBER() OVER (PARTITION BY ...), then filter - Conditional aggregation:
SUM(CASE WHEN ... THEN 1 ELSE 0 END)to count several things in one pass - Period-over-period: aggregate by period, then
LAG - Running totals:
SUM(...) OVER (ORDER BY ...) - Deduplication:
ROW_NUMBER()and keep row 1 - Gaps and islands: find streaks of consecutive days or values
- Self-join: compare rows in the same table (employees and their managers)
When you solve a problem, write down which pattern it used. After 30 or 40 problems, you'll start seeing the pattern in the question before you've written a line.
A Practice Progression
Here's a reasonable order to work through. The numbers are guidelines; move on when the current level feels comfortable, not when you hit an exact count.
- Fundamentals: SQLBolt or SQLZoo (all the interactive lessons). Short, guided exercises. If you've finished a course, you can probably move quickly.
- Easy problems: LeetCode's "SQL 50" study plan or HackerRank's SQL track (around 30–50 easy problems). Focus on solving them with the 5-step method, not on speed.
- Interview-style medium problems: DataLemur or StrataScratch (around 50 problems). These use realistic business questions and introduce the patterns above.
- Realistic investigations: scenario-based practice like the cases on SQL Side Quest, where you explore an unfamiliar database and decide which tables matter yourself, the way real work feels.
- Hard puzzles: Advanced SQL Puzzles, LeetCode hard. Come back here once mediums feel routine. They'll still be hard, but they'll be hard in a productive way.
Two habits that make practice stick
- Re-solve problems a week later without looking. If you only understood the solution, you won't be able to. That's the signal to practice that pattern again.
- Set a time limit. Give yourself 20–30 minutes, then read the solution, then close it and write it from memory. Struggling for an hour has diminishing returns; struggling for 20 minutes and then studying the answer is often faster.
Try the Method on a Case
The cases in Murder in Blackwater Bay are built for exactly this skill: you get a question and a database, and you decide how to break it down. The story gives you a reason to keep going when a step gets hard.
