SQL Unpivot Data

The reverse of pivoting — turn columns back into rows, with UNION ALL.

What & Why

Unpivoting takes wide data (separate columns per category) and turns it back into long data (one row per category). The standard Postgres approach is a UNION ALL of one SELECT per original column.

See How It Works

BUSINESS QUESTION

Product wants control and alternative participant counts returned as one row per experiment and variant group.

idexperiment_namevariantuser_idenrolled_atconvertedconverted_at
1Onboarding Copycontrol1012024-01-18 10:00:00+00true2024-01-20 09:30:00+00
2Onboarding Copyshort_copy1022024-01-18 10:05:00+00falseNULL
3Upgrade Promptcontrol1032024-03-15 08:00:00+00true2024-03-18 12:45:00+00
4Upgrade Promptannual_first1042024-03-15 08:04:00+00NULLNULL
EXAMPLE QUERY
WITH pivoted AS (
  SELECT
    experiment_name,
    COUNT(*) FILTER (WHERE variant = 'control') AS control_users,
    COUNT(*) FILTER (WHERE variant <> 'control') AS alternative_users
  FROM product.ab_tests
  GROUP BY experiment_name
)
SELECT experiment_name, 'control' AS variant_group, control_users AS users FROM pivoted
UNION ALL
SELECT experiment_name, 'alternative', alternative_users FROM pivoted
ORDER BY experiment_name, variant_group;
RESULT — pivoted variant groups returned as rows
experiment_namevariant_groupusers
Onboarding Copyalternative1
Onboarding Copycontrol1
Upgrade Promptalternative1
Upgrade Promptcontrol1

UNION ALL emits both groups for each experiment, and the final ORDER BY places alternative before control.

This lesson's practice is part of Pro.

Advanced business practice

Sign up free to try it on a real business scenario