ROLLUP in MySQL
Introduction
Business reports need subtotals and grand totals without complex UNION queries.
ROLLUP in MySQL automatically generates summary rows when used with GROUP BY.
It is widely used for:
- Hierarchical summaries (city→department→total)
- Financial reporting
- Dashboard aggregations
What is ROLLUP
ROLLUP is a GROUP BY modifier that adds subtotal and grand total rows.
It creates multiple grouping levels from right to left in GROUP BY columns.
Basic Syntax
sql
SELECT column1, column2, AGGREGATE_FUNCTION(column)
FROM table_name
GROUP BY column1, column2 WITH ROLLUP;
Example
sql
SELECT city, COUNT(*) as student_count
FROM Students
GROUP BY city WITH ROLLUP;
Shows count per city + total row with NULL city.
ROLLUP Multiple Levels
Creates all subtotal combinations.
sql
SELECT city, department, AVG(marks) as avg_marks
FROM Students
GROUP BY city, department WITH ROLLUP;
Results:
- Individual city+department rows
- City subtotals (department=NULL)
- total (city+department=NULL)
ROLLUP Result Pattern
For GROUP BY col1, col2 WITH ROLLUP:
- col1, col2 (detail rows)
- col1, NULL (col1 subtotals)
- NULL, NULL (total)
ROLLUP with ORDER BY
Control display order.
sql
SELECT city, department, COUNT(*) as count
FROM Students
GROUP BY city, department WITH ROLLUP
ORDER BY city, department;
ROLLUP with WHERE Clause
Filter before rollup calculation.
sql
SELECT city, COUNT(*) as high_scorers
FROM Students
WHERE marks > 80
GROUP BY city WITH ROLLUP;
ROLLUP with Multiple Aggregates
Multiple calculations per level.
sql
SELECT city,
COUNT(*) as total_students,
AVG(marks) as avg_marks,
SUM(marks) as total_marks
FROM Students
GROUP BY city WITH ROLLUP;
ROLLUP with JOIN
Summary across joined tables.
sql
SELECT c.course_name, COUNT(s.id) as enrollment
FROM Courses c
JOIN Students s ON c.id = s.course_id
GROUP BY c.course_name WITH ROLLUP;
Identifying ROLLUP Rows
NULL values indicate summary levels.
sql
SELECT
IF(city IS NULL, 'GRAND TOTAL', city) as city_display,
COUNT(*) as student_count
FROM Students
GROUP BY city WITH ROLLUP;
ROLLUP vs GROUPING SETS
ROLLUP is shorthand for specific sets:
GROUP BY col1, col2 WITH ROLLUP =
GROUP BY (col1,col2), (col1), ()
Execution Order with ROLLUP
ROLLUP processes after:
FROM → WHERE → GROUP BY (with ROLLUP) → HAVING → SELECT → ORDER BY → LIMIT
Performance Considerations
- ROLLUP multiplies result rows (N+1 levels)
- Index GROUP BY columns left-to-right
- Use WHERE to reduce rows before ROLLUP
- Large datasets: consider application-level totals
Important Notes
- NULL in rightmost GROUP BY column = subtotal
- All NULLs = grand total
- Works only with GROUP BY
- MySQL 8.0+ optimised ROLLUP performance
- Combine with COALESCE for readable NULLs
Example Scenario
Sales report by region→product→total:
sql
SELECT
COALESCE(region, 'ALL REGIONS') as region,
COALESCE(product, 'ALL PRODUCTS') as product,
COUNT(*) as orders,
SUM(amount) as total_sales
FROM Orders
GROUP BY region, product WITH ROLLUP
ORDER BY region NULLS LAST, product NULLS LAST;
Common Mistakes
- ROLLUP without GROUP BY (syntax error)
- Forgetting indexes on GROUP BY columns
- Misinterpreting NULL summary rows
- Large tables without WHERE filtering
- ORDER BY disrupting the ROLLUP hierarchy
Key Points to Remember
- ROLLUP adds automatic subtotals/grand totals
- Right-to-left grouping levels (col2→col1→total)
- NULL values mark summary rows
- Essential for hierarchical reporting
- Index GROUP BY columns for performance
- Use COALESCE/IF for readable NULL displays