What You'll Master Here
Set operators combine results vertically, by position. Reshaping moves values between the row axis and the column axis. Both are about shape, never about which rows are true.
Two queries can be correct and still hand back the wrong SHAPE. A chart wants one row per month and metric; a slide wants one column per month; a finance report wants a total row under the detail. Reshaping is the work of getting from one to the other.
This chapter covers the two families that do it. Set operators — UNION, UNION ALL, INTERSECT, EXCEPT — stack and compare whole result sets. Reshaping — pivot, unpivot, and subtotals — moves values between rows and columns.
Everything is taught in the portable form first, because the convenient syntax is the least portable part of SQL. There is no PIVOT in PostgreSQL, no UNPIVOT in most engines, and no GROUPING SETS in SQLite — but conditional aggregation and UNION ALL work everywhere.
Set operators combine results vertically, by position. Reshaping moves values between the row axis and the column axis. Both are about shape, never about which rows are true.
These are the queries that sit between a warehouse and a dashboard, and the ones that get rewritten every time somebody changes engines. Knowing the portable form means the rewrite is a five-minute job rather than a redesign.
- set operator
- UNION, UNION ALL, INTERSECT or EXCEPT — combines two result sets by comparing whole rows, matched by position rather than by name.
- pivot
- Moving values from rows into columns: three months of revenue become three columns.
- unpivot
- The opposite: several metric columns become one row per metric. Harder, because the column names have to be typed as literals.
- subtotal row
- A row that summarises the rows above it. ROLLUP emits them with NULL in the grouping column, which is why GROUPING() exists.
Reaching for the engine-specific PIVOT clause first. The query is unportable, and on most engines it does not exist at all — so the same report has to be rewritten per warehouse.
Say the target shape out loud before writing: how many rows, which columns.
Reach for the portable form unless the dialect one is measurably better.
Check the row count after any set operator — it is the fastest way to spot a mismatched branch.
Reshaping questions are usually asked as "produce this table", with the shape drawn on the whiteboard. Restating the target shape — row grain, column list, what goes in an empty cell — before writing anything is most of the mark.
Shape is a requirement like any other. Decide it before you write, not after the numbers come back.
