Advanced Aggregations, GROUPING SETS & Rollups

Master multidimensional data aggregation in SQL using GROUPING SETS, CUBE, ROLLUP, the GROUPING() indicator function, and pivoting techniques.

🏬 Multidimensional Data Aggregation

In corporate business intelligence (BI) reporting, financial analysts frequently request summary metrics across multiple dimensions simultaneously (e.g., total sales by Region, total sales by Product Category, total sales by Region + Category, and Grand Total).

Writing separate GROUP BY queries linked together via UNION ALL forces the database engine to perform multiple full table scans over big datasets. SQL provides multidimensional aggregation operators (GROUPING SETS, ROLLUP, CUBE) to calculate all dimensional subtotals in a single efficient table pass:

  • Analogy: A Corporate Executive Financial Reporting Dashboard.
    • GROUP BY: Printing a single regional sales report.
    • GROUPING SETS: Custom-selecting a bundle of specific summary reports (Region, Category, Region+Category) printed simultaneously.
    • ROLLUP: Hierarchical drilling (Year $\rightarrow$ Quarter $\rightarrow$ Month $\rightarrow$ Grand Total).
    • CUBE: Generating every possible combinatorial permutation of metric cards ($2^N$ summary combinations).
                      Multidimensional Aggregators

    ┌───────────────────────────────┼───────────────────────────────┐
    ▼                               ▼                               ▼
GROUPING SETS ((r), (c), (r,c))   ROLLUP (year, quarter, month)     CUBE (region, product)
Calculates specific subtotal sets Hierarchical subtotal rollup      Generates all 2^N (4) permutations

🎛️ Multidimensional Operators: Syntax & Behaviors

1. GROUPING SETS: Targeted Dimension Subtotals

Specifies explicit combinations of columns to aggregate:

-- Computes 3 distinct aggregations in ONE query pass:
-- 1. Total sales by region
-- 2. Total sales by product_category
-- 3. Grand total ()
SELECT region, product_category, SUM(sales_amount) AS total_sales
FROM sales
GROUP BY GROUPING SETS (
    (region),
    (product_category),
    ()
);

2. ROLLUP: Hierarchical Drill-Down Subtotals

Generates hierarchical subtotals and a grand total based on column order:

-- ROLLUP (year, quarter, month) generates 4 subtotal levels:
-- 1. (year, quarter, month)
-- 2. (year, quarter)
-- 3. (year)
-- 4. () [Grand Total]
SELECT year, quarter, month, SUM(revenue) AS total_revenue
FROM financial_sales
GROUP BY ROLLUP (year, quarter, month);

3. CUBE: Full Combinatorial Power Sets

Generates all $2^N$ possible subtotal combinations across $N$ columns:

-- CUBE (region, category) generates 2^2 = 4 subtotal levels:
-- 1. (region, category)
-- 2. (region)
-- 3. (category)
-- 4. () [Grand Total]
SELECT region, category, SUM(sales) AS total_sales
FROM sales
GROUP BY CUBE (region, category);

🔍 Disambiguating Subtotal NULLs with GROUPING()

When ROLLUP or CUBE generates subtotal rows, it inserts NULL into the un-aggregated dimensional columns. However, if your raw table data already contains genuine NULL values (e.g., unassigned regions), standard queries cannot distinguish between a real data NULL and an aggregation subtotal NULL.

SQL provides the GROUPING(col) indicator function:

  • Returns 1 if the column NULL was generated as an aggregation subtotal marker.
  • Returns 0 if the column NULL originates from raw table data.
SELECT 
    CASE WHEN GROUPING(region) = 1 THEN 'All Regions (Subtotal)' 
         ELSE COALESCE(region, 'Unknown Region') 
    END AS region_label,
    CASE WHEN GROUPING(category) = 1 THEN 'All Categories (Subtotal)' 
         ELSE COALESCE(category, 'Uncategorized') 
    END AS category_label,
    SUM(sales_amount) AS total_sales
FROM sales
GROUP BY ROLLUP (region, category);

🔄 Pivot & Unpivot Patterns

Pivoting transforms row-based categorical data into horizontal column headers using conditional aggregation (CASE WHEN inside aggregate functions):

-- Pivoting monthly sales rows into quarterly columns
SELECT year,
       SUM(CASE WHEN quarter = 'Q1' THEN revenue ELSE 0 END) AS Q1_Revenue,
       SUM(CASE WHEN quarter = 'Q2' THEN revenue ELSE 0 END) AS Q2_Revenue,
       SUM(CASE WHEN quarter = 'Q3' THEN revenue ELSE 0 END) AS Q3_Revenue,
       SUM(CASE WHEN quarter = 'Q4' THEN revenue ELSE 0 END) AS Q4_Revenue,
       SUM(revenue) AS Total_Yearly_Revenue
FROM quarterly_financials
GROUP BY year
ORDER BY year;

❓ Conceptual Quizzes

Knowledge Check

What is the key difference between ROLLUP(year, month) and CUBE(year, month)?

Knowledge Check

What does a GROUPING(region) value of 1 indicate in a ROLLUP query?


💻 Practice Problems

Problem: Single-Pass Multi-Level Regional Sales Matrix

Write a single SQL query against store_sales (country, state, sales) that computes:

  1. Sales by country and state
  2. Total sales by country
  3. Overall grand total sales Use the GROUPING() function to output "All Countries" and "All States" in place of subtotal NULLs.

On this page