SELECT-FROM-WHERE: The SQL Foundation
Concept. Every basic query has three clauses: FROM picks the table, WHERE keeps the rows that pass a test, SELECT chooses the columns to return.
Intuition. You write SELECT-FROM-WHERE, but it runs FROM, then WHERE, then SELECT: load all of Listens, drop the rows that fail the rating test, then keep just the columns you asked for.
Figure 1. WHERE drops rows that fail its test, and SELECT keeps only the columns you name. FROM loads first, so the clauses run FROM, then WHERE, then SELECT. WHERE strikes the rows that fail its test (nine down to five, and a NULL comparison is UNKNOWN so it drops too), and SELECT keeps only the columns you name (dropping listen_id).
Basic Query Structure: The FloWS Order
-- Get listens with high ratings (above 4.0)
SELECT user_id, song_id, rating -- choose only 3 columns for output
FROM Listens -- picks the table (9 rows)
WHERE rating > 4.0 -- keeps rows where the test is TRUE
-
Execution Order: FROM → WHERE → SELECT. Read it as FWS (FloWS mnemonic). That is the reverse of the SFW you write.
-
Row Filtering: WHERE evaluates each row individually
-
Column Selection: SELECT determines output columns
You write SELECT first, but the database runs it last: it needs the table (FROM) and the surviving rows (WHERE) before it can decide what to return (SELECT).
WHERE with AND and OR
-- AND: both conditions must hold
SELECT user_id, song_id, rating
FROM Listens
WHERE user_id = 1 AND rating > 4.0
-- OR: either condition is enough
SELECT user_id, song_id, rating
FROM Listens
WHERE user_id = 1 OR rating > 4.0
Figure 2. AND keeps a row only when both checks pass, so two rows survive. OR keeps a row when either passes, so six survive. The NULL rating makes rating > 4.0 UNKNOWN, which neither AND nor OR can turn into a keep.
Understanding Aliases (AS Keyword)
An alias gives a column a new name in the output with AS. But because WHERE runs before SELECT, the alias does not exist yet when WHERE is evaluated, so WHERE cannot use it.
Figure 3. AS renames a column in the result, but only in SELECT, which runs last. Since WHERE runs before SELECT, the alias does not exist yet there: WHERE double_rating > 8 fails, while WHERE rating * 2 > 8 works because the expression itself already exists.
Why It Matters:
| Clause | Execution Order | Can Reference | Cannot Reference |
|---|---|---|---|
| FROM | 1st | Table names | SELECT aliases |
| WHERE | 2nd | Table columns | SELECT aliases |
| SELECT | 3rd | Table columns, expressions | Future aliases |
SELECT with Calculations
SELECT can also compute new columns. rating * 2 AS double_rating doubles a value; CASE ... WHEN is SQL's if-then-else.
SELECT
user_id,
rating,
rating * 2 AS double_rating,
CASE
WHEN rating >= 4.5 THEN 'Excellent'
WHEN rating >= 4.0 THEN 'Good'
ELSE 'Average'
END AS category
FROM Listens
WHERE rating IS NOT NULL
| user_id | rating | double_rating | category | |
|---|---|---|---|---|
| 1 | 4.5 | 9.0 | Excellent | |
| 1 | 4.2 | 8.4 | Good | |
| 1 | 3.9 | 7.8 | Average | |
| 2 | 4.7 | 9.4 | Excellent | |
| 3 | 4.9 | 9.8 | Excellent |