Subqueries and CTEs
CTE
Naming an Intermediate Result
A common table expression gives a query result a temporary name.
Program
Play the query to build totals, then filter it.
cte_totals.sql
Replay: real traced execution (multi-file project)
CREATE TABLE sales (item TEXT, qty INTEGER);
INSERT INTO sales VALUES ('book', 2), ('pen', 5), ('book', 3);
WITH totals AS (SELECT item, SUM(qty) AS sold FROM sales GROUP BY item) SELECT item, sold FROM totals WHERE sold >= 5 ORDER BY item;
sales ← 0 rows
1CREATE TABLE sales (item TEXT, qty INTEGER);2INSERT INTO sales VALUES ('book', 2), ('pen', 5), ('book', 3);values this step0 rowssalessales ← 3 rows
1CREATE TABLE sales (item TEXT, qty INTEGER);2INSERT INTO sales VALUES ('book', 2), ('pen', 5), ('book', 3);3WITH totals AS (SELECT item, SUM(qty) AS sold FROM sales GROUP BY item) SELECT item, sold FROM totals WHERE sold >= 5 ORDER BY item;values this step3 rowssalesresult ← 2 rows
2INSERT INTO sales VALUES ('book', 2), ('pen', 5), ('book', 3);3WITH totals AS (SELECT item, SUM(qty) AS sold FROM sales GROUP BY item) SELECT item, sold FROM totals WHERE sold >= 5 ORDER BY item;values this step2 rowsresult
Follow the CTE
- The
salesrows arebook 2,pen 5, andbook 3. - The CTE groups matching item names together.
booktotals2 + 3, which is5.pentotals5.WHERE sold >= 5keeps both grouped rows. | item | rows added | sold | kept? | | --- | --- | --- | --- | | book | 2 + 3 | 5 | yes | | pen | 5 | 5 | yes |
WITH
`WITH totals AS (...)` names an intermediate query.
temporary table
The CTE behaves like a temporary table for the following `SELECT`.
readability
CTEs make multi-step queries easier to read.
Exercise: cte_totals.sql
Reproduce the grouped totals book=5 and pen=5, then predict which rows pass the sold >= 5 filter.