Grouping & aggregation

Subtotals and grand totals with ROLLUP

3 min · updated August 21, 2026

ROLLUP adds subtotal rows for each level plus a grand total, without a separate UNION.

-- Sales by region and category, with per-region subtotals and a grand total
SELECT region, category, SUM(amount) AS total
FROM sales
GROUP BY ROLLUP (region, category)
ORDER BY region, category;

The extra rows have NULL in the rolled-up columns. Label them with GROUPING():

SELECT
  CASE WHEN GROUPING(region) = 1 THEN 'All regions' ELSE region END AS region,
  CASE WHEN GROUPING(category) = 1 THEN 'All categories' ELSE category END AS category,
  SUM(amount) AS total
FROM sales
GROUP BY ROLLUP (region, category);

Dialect notes:

SELECT region, category, SUM(amount) FROM sales GROUP BY region, category
UNION ALL SELECT region, NULL, SUM(amount) FROM sales GROUP BY region
UNION ALL SELECT NULL, NULL, SUM(amount) FROM sales;

← All recipes