Grouping & aggregation

Pivot rows into columns

3 min read

The portable way to pivot is conditional aggregation — one SUM(CASE WHEN …) per output column. This works in every dialect:

SELECT
  product,
  SUM(CASE WHEN quarter = 'Q1' THEN amount END) AS q1,
  SUM(CASE WHEN quarter = 'Q2' THEN amount END) AS q2,
  SUM(CASE WHEN quarter = 'Q3' THEN amount END) AS q3,
  SUM(CASE WHEN quarter = 'Q4' THEN amount END) AS q4
FROM sales
GROUP BY product;

BigQuery, Snowflake and DuckDB also have a dedicated PIVOT operator:

-- BigQuery / Snowflake / DuckDB
SELECT *
FROM sales
PIVOT (SUM(amount) FOR quarter IN ('Q1', 'Q2', 'Q3', 'Q4'));

No PIVOT in MySQL, PostgreSQL or SQLite. Use the CASE form above. (PostgreSQL has crosstab() but it needs the tablefunc extension and rigid column typing — the CASE form is simpler and needs nothing installed.) The pivot column values must be known in advance; for a dynamic set of columns you have to build the SQL string in your app.

Open the full version (with copy buttons) ↗

← All recipes