Where we are
Last session you learned that a database is just organized tables and that every metric is a SQL query underneath. Today we slow down and read. By the end you will be able to look at any simple query and say - out loud, in a meeting - which facts it asks for, from which list, filtered how, and summarized per what. That is the reading fluency that lets you challenge a number instead of nodding at it.
The anatomy, in business terms 7 min live
A query is built from clauses, and each clause answers one plain-English question. Learn these four and you can read most of what crosses your desk: SELECT = which facts, FROM = which list, WHERE = filtered how, GROUP BY = summarized per what. Read them in that order and the query tells you its own story.
LiveRead this one aloud, then run it3 min▶
Before you press Run, say it as a sentence: "give me the name and city, from the customers list, filtered to the ones in the USA." That is the whole query in English. Now run it and confirm the answer matches what you just said - only US customers, only two columns.
SELECT name, city FROM customers WHERE country = 'USA';
Self-studyThe four anchor words, in one table2 min read▶
Keep this close for your first few query reviews. Four words carry most of the meaning; everything else is detail.
| Clause | In business terms | Question it answers |
|---|---|---|
SELECT | which facts | what columns do I get back? |
FROM | which list | which table are we pulling from? |
WHERE | filtered how | which rows qualify? |
GROUP BY | summarized per what | one row per country? per month? |
Notice that GROUP BY is the one that quietly changes a number into an "average per" or "count per" - the source of most metric confusion, which is exactly what session a3 unpacks.
What a filter does to a number 6 min live
Here is the single most useful thing a leader can internalize about SQL: the same table, filtered, is a different metric. "How many orders do we have?" has more than one true answer, and the WHERE clause is what decides which one you are looking at. Watch two legitimate "order counts" come out of the same table.
LiveAll orders - the raw count2 min▶
COUNT(*) means "count the rows". This one counts every order in the table, no matter its status. Read it: "count all rows in orders." Run it and note the number.
SELECT COUNT(*) AS all_orders FROM orders;
LiveCompleted orders - a filtered count2 min▶
Same table, one line added. The WHERE clause keeps only the rows whose status is completed. Read it: "count the rows in orders where the status is completed." Run it - the number is smaller, because the refunded and cancelled orders dropped out.
SELECT COUNT(*) AS completed_orders FROM orders WHERE status = 'completed';
Which one belongs in the board deck? Both counts are honest. "All orders" is right for operations volume; "completed orders" is right for revenue-linked reporting. The mistake is putting one on a slide labelled simply "orders" and letting the room assume the other. When someone shows you an order count, the leader's reflex is one question: which statuses did this include?
What a JOIN means 6 min live
Your orders table stores a customer_id, not a name - just a number pointing at the customers list. A JOIN is how SQL stitches the two lists together on that shared id, so you can see the order and the human who placed it in one row. You never need to write a join. You do need to know that this is what "we joined orders to customers" means.
LiveStitch each order to its customer3 min▶
Read past the punctuation to the idea: "give me the order id and the customer name, from orders joined to customers on the shared customer id, first six." The o and c are just short nicknames for the two tables. Run it and watch order numbers line up with real names.
SELECT o.order_id, c.name FROM orders o JOIN customers c ON o.customer_id = c.customer_id LIMIT 6;
Self-studyWhy joins are where reports quietly break2 min read▶
Joins are powerful and also where subtle errors creep in. Two are worth knowing by name, so you can ask about them:
- Dropped rows: if an order points at a customer id that no longer exists, a plain join can silently drop that order - and your total quietly shrinks. Ask: "did anything fall out of the join?"
- Doubled rows: if a customer matches many rows, a join can multiply a count. This is the classic cause of a number that looks suspiciously too big. Ask: "could this join have duplicated anything?"
You are not debugging the join. You are the person in the room who knows those two questions exist - which is often the difference between a caught error and a bad decision.
Read three queries as a group ★ 12 min · discuss together
No code to write. For each query, state the business question it answers before anyone runs it. Only then press Run and check whether the group read it right. The muscle you are building is turning keywords into a plain sentence, fast.
Query A: what business question does it answer? Predict the shape of the result, then run.
Query B: which clause makes this a "per something" summary? Say the "per what" out loud before running.
Query C: which two lists does this join, and on what shared id? Name them, then run.
LiveQuery A · who signed up on the Pro plan3 min▶
SELECT name, country FROM customers WHERE plan = 'Pro';
LiveQuery B · customers summarized per country3 min▶
The GROUP BY is the tell: this is not a list of customers, it is a count per country. Say the "per what" before running.
SELECT country, COUNT(*) AS customers FROM customers GROUP BY country;
LiveQuery C · orders with their customer's city3 min▶
Name the two lists and the shared id before you run. This stitches each order to the city of the customer who placed it.
SELECT o.order_id, c.city FROM orders o JOIN customers c ON o.customer_id = c.customer_id LIMIT 6;
Take this back to your desk ◐ 15 min
- Pick one metric from a report you receive weekly. Ask your analyst to say it as a sentence in the four-anchor form: which facts, from which list, filtered how, per what. Notice how much sharper the metric becomes once it is stated that way.
- Come back and run the "all orders" versus "completed orders" pair again until the idea that a filter changes the metric feels obvious. Obvious is the goal.
- Next time someone says "we joined the data", ask which two lists and on what shared id. You now know that is a fair, answerable question.
- Optional: skim the builder track's session on WHERE and JOIN to see the same ideas from the writer's side. You will recognize every concept.
What this maps to
This session distills the reading half of the standard SQL curriculum - understanding a query's structure - without the drills a practitioner needs to write one. It covers:
Three questions before you go 🎯 ◐ 90 seconds
1 · When a query has a GROUP BY, it is a signal that...
GROUP BY turns a list into a "per what" summary. Reading it means asking: one row per country? per month? That "per" is where most metric confusion lives.
2 · Two different "order counts" come out of the same table because...
The same table, filtered, is a different metric. A WHERE clause on status turns "all orders" into "completed orders". Both are true; they answer different questions.
3 · A JOIN, in business terms, does what?
A join stitches two lists together on a shared id, so an order can show the name of the customer who placed it. You read joins; you do not need to write them.