learn-sql-with-phoebe / Leader session 2 of 6
Learn SQL with Phoebe · Leader track · Session 2 of 6

Reading a query without fear

A query looks like a wall of keywords until you learn the four anchor words and what each one does to the answer. In this session you build reading fluency: look at a query, say the business question it asks, predict the result, then run it to confirm. No writing, no memorizing - just the calm confidence to read what your data team hands you.

🟢 Leader track C-level · managers · curious non-coders No install · nothing to write 45 min
0-3 · Recap 3-21 · The anatomy of a query 21-39 · Filters & joins 39-45 · Q&A
Part 0

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.

Live - discussed in session Self-study - read after ▶ See it run - a real query, live For decision-makers
★ What you walk out with today The four anchor clauses of a query in plain English, the instinct that a filter turns one metric into a completely different metric, and a working feel for what a JOIN does - so "we stitched orders to customers" stops sounding like magic.
Part 1 · the mental model

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.

SELECT name FROM customers WHERE country Which facts the columns you want back Which list the table you pull from Filtered how the rows that qualify Summarized per what GROUP BY, when present Read a query in this order and it narrates its own business question.
🔍 Click to zoom - the four clauses, each a plain-English question
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';
The read-aloud test If you can turn a query into one plain sentence before running it, you can review it in a meeting. That is the leader's bar - not writing the query, reading it with confidence.
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.

ClauseIn business termsQuestion it answers
SELECTwhich factswhat columns do I get back?
FROMwhich listwhich table are we pulling from?
WHEREfiltered howwhich rows qualify?
GROUP BYsummarized per whatone 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.

Part 2 · why one word matters

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.

orders - 33 rows order_idstatus 1004completed 1005completed 1006refunded 1007completed 1014cancelled 1017refunded … 27 more rows, all completed SELECT COUNT(*) FROM orders; SELECT COUNT(*) FROM orders WHERE status = 'completed'; 33 all_orders every status counts 30 completed_orders 1006, 1014, 1017 drop out Both numbers are honest: 33 is operations volume, 30 is revenue-linked. One WHERE line is the whole difference.
🔍 Click to zoom - one table, two true order counts: the WHERE line decides which
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';
Real world

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?

Part 3 · combining two lists

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.

orders (o) order_idcustomer_id 10011 10022 10033 10041 10055 10064 customers (c) customer_idname 1Ava Chen 2Liam Ford 3Noah Park 4Mia Wong 5Ethan Ruiz JOIN ... ON the shared customer_id one stitched row per order order_idname 1001Ava Chen 1002Liam Ford 1003Noah Park 1004Ava Chen 1005Ethan Ruiz 1006Mia Wong Each order carries only a customer_id; the join follows that id into customers and brings the name back. Ava Chen appears twice because she placed orders 1001 and 1004 - a matched row, not a duplicate.
🔍 Click to zoom - a JOIN follows the shared id and brings the name back to each order
SELECT o.order_id, c.name
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
LIMIT 6;
The one-line read of any JOIN "This stitches each order to the customer who placed it." If you can say which two lists are being joined and on what shared id, you have read the join well enough to question it.
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.

Boardroom exercise

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;
Between sessions

Take this back to your desk ◐ 15 min

Source material

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:

Mode SQL Tutorial - Basic & Intermediate (reading level)Parts 1-3 · SELECT / FROM / WHERE / GROUP BY / JOIN, read not written
Filters change the metric - counts with and without WHEREPart 2 · the same table filtered is a different number
Khan Academy - Intro to SQL (reading a JOIN conceptually)Part 3 · combining two lists on a shared id, in business language
Check yourself

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.

Leader session 2 cheat sheet · pin this

SELECTwhich facts - the columns you want back.
FROMwhich list - the table you pull from.
WHEREfiltered how - which rows qualify. This changes the metric.
GROUP BYsummarized per what - per country, per month. Watch this one.
A filter is a metric"all orders" vs "completed orders" are two true, different numbers.
A JOINstitches two lists on a shared id - orders to the customer who placed them.
Join risks to ask aboutcould rows have dropped out, or duplicated and inflated a count?
Next sessiona3 · judging a data claim - when a number quietly misleads.