Если возможностей ROLLUP и CUBE не хватает, то можно наборы группирования задать самому через GROUPING SETS.

Синтаксис:

GROUP BY GROUPING SETS ((выражение_11, выражение_12, ... выражение_1n), ... (выражение_m1, выражение_m2, ... выражение_mk))

В каждом внутреннем списке GROUPING SETS могут задаваться ноль или более столбцов или выражений, которые воспринимаются так же, как если бы они были непосредственно записаны в предложении GROUP BY. Пустой набор группировки означает, что все строки сводятся к одной группе (которая выводится, даже если входных строк нет), как для агрегатных функций без предложения GROUP BY.

Значения полей из GROUP BY, по которым не производилась группировка, в результате выполнения запроса будут равны NULL.

Рассмотрим пример, аналогичный заданию CUBE. Получим минимальную и максимальную цены на товары в городах с идентификаторами 2 и 4 по:

  • только по городу;
  • только по категории товара;
  • по всем строкам.

Исходные данные:

SELECT sa.city_id, 
       p.category_id,
       pp.price
  FROM product_price pp
  JOIN product p
    ON p.product_id = pp.product_id
  JOIN store_address sa
    ON sa.store_id = pp.store_id
 WHERE sa.city_id IN (2, 4)
 ORDER BY sa.city_id,
          p.category_id,
          pp.price
city_id category_id price
1 2 6 21500.00
2 2 6 22900.00
3 2 6 23500.00
4 2 7 17800.00
5 4 6 20000.00
6 4 8 37000.00
7 4 9 75600.00

Добавим GROUPING SETS:

SELECT sa.city_id, 
       p.category_id,
       min(pp.price) AS price_min,
       max(pp.price) AS price_max
  FROM product_price pp
  JOIN product p
    ON p.product_id = pp.product_id
  JOIN store_address sa
    ON sa.store_id = pp.store_id
 WHERE sa.city_id IN (2, 4)
 GROUP BY GROUPING SETS ((sa.city_id), (p.category_id), ())
 ORDER BY sa.city_id NULLS LAST,
          p.category_id NULLS LAST
# city_id category_id price_min price_max
1 2 NULL 17800.00 23500.00
2 4 NULL 20000.00 75600.00
3 NULL 6 20000.00 23500.00
4 NULL 7 17800.00 17800.00
5 NULL 8 37000.00 37000.00
6 NULL 9 75600.00 75600.00
7 NULL NULL 17800.00 75600.00

Повнимательнее рассмотрим результат.

Строки

# city_id category_id price_min price_max
1 2 NULL 17800.00 23500.00
2 4 NULL 20000.00 75600.00

получены в результате GROUP BY sa.city_id (итоги по городам).

Строки

# city_id category_id price_min price_max
3 NULL 6 20000.00 23500.00
4 NULL 7 17800.00 17800.00
5 NULL 8 37000.00 37000.00
6 NULL 9 75600.00 75600.00

получены в результате GROUP BY p.category_id (итоги по категориям).

Строка

# city_id category_id price_min price_max
7 NULL NULL 17800.00 75600.00

является результатом вычисления итогов по всем строкам.

4.12 CUBE

5.1 Доступные операции над множествами