Skip to main content

When to use this

Sometimes your data is in the wrong shape for the analysis you need. Pivoting turns distinct row values into columns (e.g., turning monthly rows into one column per month). Unpivoting does the reverse — turning columns into rows (e.g., turning q1_revenue, q2_revenue, q3_revenue columns into quarter and revenue rows).

Sample input — Pivot

A monthly_sales table in the Raw layer, with one row per product per month: We want one row per product with a column for each month.

Sample input — Unpivot

A quarterly_revenue table where each quarter is a separate column: We want to normalize this into product, quarter, and revenue columns.

Implementation — Pivot

BigQuery supports a native PIVOT clause for cleaner syntax.
The values in the IN clause must be known at query time. If your months are dynamic, use the conditional aggregation approach shown in the Athena tab.

Pivot — Expected output


Implementation — Unpivot

BigQuery supports a native UNPIVOT clause.

Unpivot — Expected output


Tips and gotchas

Pivoting requires knowing the distinct values upfront (months, quarters, etc.). If the values change over time, you’ll need to update the query. For fully dynamic pivots, the Python approach is the most flexible — you can read distinct values from the data and build the pivot programmatically.
After pivoting, column names come from data values and may contain spaces, special characters, or start with numbers. Clean them up with Rename columns if needed.