PENGELOMPOKAN(expr [, expr] ...)
SELECT * FROM t1;
+------+-------+----------+
| name | size | quantity |
+------+-------+----------+
| ball | small | 10 |
| ball | large | 20 |
| ball | NULL | 5 |
| hoop | small | 15 |
| hoop | large | 5 |
| hoop | NULL | 3 |
+------+-------+----------+
For GROUP BY queries that include a WITH ROLLUP modifier, the ROLLUP operation produces super-aggregate output rows where NULL represents the set of all values. The GROUPING() function enables you to distinguish NULL values for super-aggregate rows from NULL values in regular grouped rows.
SELECT * FROM t1;
+------+-------+----------+
| name | size | quantity |
+------+-------+----------+
| ball | small | 10 |
| ball | large | 20 |
| ball | NULL | 5 |
| hoop | small | 15 |
| hoop | large | 5 |
| hoop | NULL | 3 |
+------+-------+----------+
GROUPING() is permitted in the select list, HAVING clause, and ORDER BY clause.
SELECT name, size, SUM(quantity) AS quantity
FROM t1
GROUP BY name, size;
+------+-------+----------+
| name | size | quantity |
+------+-------+----------+
| ball | small | 10 |
| ball | large | 20 |
| ball | NULL | 5 |
| hoop | small | 15 |
| hoop | large | 5 |
| hoop | NULL | 3 |
+------+-------+----------+
Each argument to GROUPING() must be an expression that exactly matches an expression in the GROUP BY clause. The expression cannot be a positional specifier. For each expression, GROUPING() produces 1 if the expression value in the current row is a NULL representing a super-aggregate value. Otherwise, GROUPING() produces 0, indicating that the expression value is a NULL for a regular result row or is not NULL.
SELECT name, size, SUM(quantity) AS quantity
FROM t1
GROUP BY name, size WITH ROLLUP;
+------+-------+----------+
| name | size | quantity |
+------+-------+----------+
| ball | NULL | 5 |
| ball | large | 20 |
| ball | small | 10 |
| ball | NULL | 35 |
| hoop | NULL | 3 |
| hoop | large | 5 |
| hoop | small | 15 |
| hoop | NULL | 23 |
| NULL | NULL | 58 |
+------+-------+----------+
Suppose that table t1 contains these rows, where NULL indicates something like “other” or “unknown”:
SELECT
name, size, SUM(quantity) AS quantity,
GROUPING(name) AS grp_name,
GROUPING(size) AS grp_size
FROM t1
GROUP BY name, size WITH ROLLUP;
+------+-------+----------+----------+----------+
| name | size | quantity | grp_name | grp_size |
+------+-------+----------+----------+----------+
| ball | NULL | 5 | 0 | 0 |
| ball | large | 20 | 0 | 0 |
| ball | small | 10 | 0 | 0 |
| ball | NULL | 35 | 0 | 1 |
| hoop | NULL | 3 | 0 | 0 |
| hoop | large | 5 | 0 | 0 |
| hoop | small | 15 | 0 | 0 |
| hoop | NULL | 23 | 0 | 1 |
| NULL | NULL | 58 | 1 | 1 |
+------+-------+----------+----------+----------+
A summary of the table without WITH ROLLUP looks like this:
SELECT
IF(GROUPING(name) = 1, 'All items', name) AS name,
IF(GROUPING(size) = 1, 'All sizes', size) AS size,
SUM(quantity) AS quantity
FROM t1
GROUP BY name, size WITH ROLLUP;
+-----------+-----------+----------+
| name | size | quantity |
+-----------+-----------+----------+
| ball | NULL | 5 |
| ball | large | 20 |
| ball | small | 10 |
| ball | All sizes | 35 |
| hoop | NULL | 3 |
| hoop | large | 5 |
| hoop | small | 15 |
| hoop | All sizes | 23 |
| All items | All sizes | 58 |
+-----------+-----------+----------+
The result contains NULL values, but those do not represent super-aggregate rows because the query does not include WITH ROLLUP.
SELECT name, size, SUM(quantity) AS quantity
FROM t1
GROUP BY name, size WITH ROLLUP
HAVING GROUPING(name) = 1 OR GROUPING(size) = 1;
+------+------+----------+
| name | size | quantity |
+------+------+----------+
| ball | NULL | 35 |
| hoop | NULL | 23 |
| NULL | NULL | 58 |
+------+------+----------+
Adding WITH ROLLUP produces super-aggregate summary rows containing additional NULL values. However, without comparing this result to the previous one, it is not easy to see which NULL values occur in super-aggregate rows and which occur in regular grouped rows:
result for GROUPING(expr3)
+ result for GROUPING(expr2) << 1
+ result for GROUPING(expr1) << 2
To distinguish NULL values in super-aggregate rows from those in regular grouped rows, use GROUPING(), which returns 1 only for super-aggregate NULL values:
SELECT
name, size, SUM(quantity) AS quantity,
GROUPING(name) AS grp_name,
GROUPING(size) AS grp_size,
GROUPING(name, size) AS grp_all
FROM t1
GROUP BY name, size WITH ROLLUP;
+------+-------+----------+----------+----------+---------+
| name | size | quantity | grp_name | grp_size | grp_all |
+------+-------+----------+----------+----------+---------+
| ball | NULL | 5 | 0 | 0 | 0 |
| ball | large | 20 | 0 | 0 | 0 |
| ball | small | 10 | 0 | 0 | 0 |
| ball | NULL | 35 | 0 | 1 | 1 |
| hoop | NULL | 3 | 0 | 0 | 0 |
| hoop | large | 5 | 0 | 0 | 0 |
| hoop | small | 15 | 0 | 0 | 0 |
| hoop | NULL | 23 | 0 | 1 | 1 |
| NULL | NULL | 58 | 1 | 1 | 3 |
+------+-------+----------+----------+----------+---------+
Common uses for GROUPING():
SELECT name, size, SUM(quantity) AS quantity
FROM t1
GROUP BY name, size WITH ROLLUP
HAVING GROUPING(name, size) <> 0;
+------+------+----------+
| name | size | quantity |
+------+------+----------+
| ball | NULL | 35 |
| hoop | NULL | 23 |
| NULL | NULL | 58 |
+------+------+----------+
Substitute a label for super-aggregate NULL values:
SELECT GROUPING((SELECT MAX(name) FROM t1))
FROM t1
GROUP BY (SELECT MAX(name) FROM t1) WITH ROLLUP;
ERROR 3580 (HY000): Argument #1 of GROUPING function is not in GROUP BY
Return only super-aggregate lines by filtering out the regular grouped lines:
SELECT a AS f1, 'w' AS f2
FROM t
GROUP BY f1, f2 WITH ROLLUP
HAVING GROUPING(f2) = 1;