WITH ROLLUP додає до результату групування рядки підсумків: для кожного рівня групування і загальний підсумок.
SELECT country, city, SUM(total) AS revenue
FROM orders
GROUP BY country, city WITH ROLLUP;
country | city | revenue
UA | Київ | 120000
UA | Львів | 45000
UA | NULL | 165000 <- підсумок по країні
PL | Krakow | 30000
PL | NULL | 30000
NULL | NULL | 195000 <- загальний підсумок
В одному запиті - і деталі, і проміжні суми, і загальна сума. Без ROLLUP довелося б об'єднувати кілька запитів через UNION ALL чи рахувати підсумки в застосунку.
Як відрізнити рядок підсумку від справжнього NULL: функція GROUPING() (MySQL 8.0.12+) повертає 1 для колонок, «згорнутих» у підсумок:
SELECT
IF(GROUPING(country), 'Усі країни', country) AS country,
IF(GROUPING(city), 'Усього', city) AS city,
SUM(total) AS revenue
FROM orders
GROUP BY country, city WITH ROLLUP;
Без цього рядок з city = NULL (замовлення без міста) неможливо відрізнити від підсумку по країні.
Що варто знати:
- Порядок колонок у
GROUP BYвизначає ієрархію:country, cityдає підсумки по країнах, але не по містах окремо від країн. ORDER BYзROLLUPдозволений з MySQL 8.0.12; раніше підсумки йшли лише в природному порядку групування.- PostgreSQL має
ROLLUP, а такожCUBE(підсумки за всіма комбінаціями) іGROUPING SETS(довільні набори групувань). MySQL підтримує лишеROLLUP.
Коли це доречно: звіти й вивантаження для бухгалтерії, де підсумки потрібні прямо в даних. Для веб-інтерфейсу підсумки часто зручніше рахувати окремим запитом чи в застосунку, щоб не змішувати рядки різного типу.