Reshaping — pivot & unpivot
Concept  ·  SQL & Querying

Unpivot with UNION ALL (or lateral VALUES) — then decide whether absent measures become NULL rows or are dropped.

Long form's grain is (entity × measure-label) — the label is not decoration, it is half the key. Carry it and UNION merely wastes a sort while your safety hangs on labels staying distinct; drop it and identical measurements become duplicates to be 'cleaned'. UNION ALL says what an unpivot means: every cell becomes exactly one row.

See it break
builds
puppetact1_minsact2_mins
alpha88
beta59
The trap
SELECT
  puppet,
  act1_mins AS mins
FROM
  builds
UNION SELECT
  puppet,
  act2_mins
FROM
  builds
ORDER BY
  puppet,
  mins;
The fix
SELECT
  puppet,
  'act1' AS act,
  act1_mins AS mins
FROM
  builds
UNION ALL
SELECT
  puppet,
  'act2',
  act2_mins
FROM
  builds
ORDER BY
  puppet,
  act;
The trap
alpha8
beta5
beta9
The fix
alphaact18
alphaact28
betaact15
betaact29

The unpivot used UNION and dropped the act label, so alpha's two identical 8-minute acts collapsed into one row — UNION ALL with a label keeps every cell as its own long-form row.

The rule

UNION ALL arms each carrying a label, a lateral VALUES clause, or a native UNPIVOT where the dialect has one.

SELECT 'q1' AS k, q1 AS v FROM t UNION ALL SELECT 'q2', q2 FROM t

Some engines offer a native UNPIVOT; the UNION ALL form is the portable spelling.

Shows up elsewhere
UNION dedups; UNION ALL doesn'tSet ops align by position
Try one →Prove it in practice →