Разберем другой встроенный набор группирования - CUBE. CUBE работает аналогично ROLLUP, только выполняет группировку по всевозможным подмножествам переданного списка выражений.
Например, для GROUP BY CUBE (a, b, c) результатом запроса будет объединение результатов GROUP BY по
- a, b, c;
- a, b;
- a, c;
- b, c;
- a;
- b;
- c;
- по всем строкам.
Синтаксис CUBE:
GROUP BY CUBE (выражение1, выражение2, ... , выражениеN)
Рассмотрим пример. Получим минимальную и максимальную цены на товары в городах с идентификаторами 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 |
Добавим GROUP BY CUBE (sa.city_id, p.category_id):
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 CUBE (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 | 6 | 21500.00 | 23500.00 |
| 2 | 2 | 7 | 17800.00 | 17800.00 |
| 3 | 2 | NULL | 17800.00 | 23500.00 |
| 4 | 4 | 6 | 20000.00 | 20000.00 |
| 5 | 4 | 8 | 37000.00 | 37000.00 |
| 6 | 4 | 9 | 75600.00 | 75600.00 |
| 7 | 4 | NULL | 20000.00 | 75600.00 |
| 8 | NULL | 6 | 20000.00 | 23500.00 |
| 9 | NULL | 7 | 17800.00 | 17800.00 |
| 10 | NULL | 8 | 37000.00 | 37000.00 |
| 11 | NULL | 9 | 75600.00 | 75600.00 |
| 12 | NULL | NULL | 17800.00 | 75600.00 |
Повнимательнее рассмотрим результат выполнения запроса. В полученном результате строки
| # | city_id | category_id | price_min | price_max |
|---|---|---|---|---|
| 1 | 2 | 6 | 21500.00 | 23500.00 |
| 2 | 2 | 7 | 17800.00 | 17800.00 |
| 4 | 4 | 6 | 20000.00 | 20000.00 |
| 5 | 4 | 8 | 37000.00 | 37000.00 |
| 6 | 4 | 9 | 75600.00 | 75600.00 |
получены в результате GROUP BY sa.city_id, p.category_id.
Строки
| # | city_id | category_id | price_min | price_max |
|---|---|---|---|---|
| 3 | 2 | NULL | 17800.00 | 23500.00 |
| 7 | 4 | NULL | 20000.00 | 75600.00 |
получены в результате GROUP BY sa.city_id (итоги по городам).
Строки
| # | city_id | category_id | price_min | price_max |
|---|---|---|---|---|
| 8 | NULL | 6 | 20000.00 | 23500.00 |
| 9 | NULL | 7 | 17800.00 | 17800.00 |
| 10 | NULL | 8 | 37000.00 | 37000.00 |
| 11 | NULL | 9 | 75600.00 | 75600.00 |
получены в результате GROUP BY p.category_id (итоги по категориям).
Строка
| # | city_id | category_id | price_min | price_max |
|---|---|---|---|---|
| 12 | NULL | NULL | 17800.00 | 75600.00 |
является результатом вычисления итогов по всем строкам.