GROUPING_ID 函数简化了 GROUPING 函数,以便确定 ROLLBACK、CUBE 或 GROUPING SETS 扩展的结果集中行的小计级别。
GROUPING 函数仅采用一个列表达式并返回一个值来指示行是否是给定列的所有值的小计。因而,解释具有多个分组列的查询的小计级别时,可能需要多个 GROUPING 函数。
GROUPING_ID 函数接受 ROLLBACK、CUBE 或 GROUPINGSETS 扩展中已使用的一个或多个列表达式,并返回单个整数,该整数可用于确定其中哪一列已聚合小计。
下面显示了使用 GROUPING_ID 函数的常规语法。
SELECT [ expr ...,]
GROUPING_ID( col_expr_1 [, col_expr_2 ] ... )
[, expr ] ...
FROM ...
GROUP BY [...,]
{ ROLLUP | CUBE | GROUPING SETS }( [...,] col_expr_1
[, col_expr_2 ] [, ...] ) [, ...]
GROUPING_ID 函数采用的一个或多个参数必须是维度列的表达式,这些列在 GROUP BY 子句的 ROLLUP、CUBE 或 GROUPING SETS 扩展表达式列表中指定。
GROUPING_ID 函数返回一个整数值。该值对应于位向量的十进制解释,该向量由串联的 1 和 0 组成,将由一系列 GROUPING 函数按从左到右的顺序返回,这与 GROUPING_ID 函数中指定参数的顺序相同。
以下查询显示 gid 列中表示的 GROUPING_ID 函数的返回值如何对应于针对 loc和 dname 列的 GROUPING 函数返回的值。
SELECT loc, dname, COUNT(*) AS "employees",
GROUPING(loc) AS "gf_loc", GROUPING(dname) AS "gf_dname",
GROUPING_ID(loc, dname) AS "gid"
FROM emp e, dept d
WHERE e.deptno = d.deptno
GROUP BY CUBE (loc, dname)
ORDER BY 6, 1, 2;
在以下输出中,您会看到 gf_loc 值和 gf_dname 值组成的位向量与 gid 中给出的整数之间的关系。
loc | dname | employees | gf_loc | gf_dname | gid
----------+------------+-----------+--------+----------+-----
BOSTON | OPERATIONS | 3 | 0 | 0 | 0
BOSTON | RESEARCH | 5 | 0 | 0 | 0
CHICAGO | SALES | 6 | 0 | 0 | 0
NEW YORK | ACCOUNTING | 3 | 0 | 0 | 0
BOSTON | | 8 | 0 | 1 | 1
CHICAGO | | 6 | 0 | 1 | 1
NEW YORK | | 3 | 0 | 1 | 1
| ACCOUNTING | 3 | 1 | 0 | 2
| OPERATIONS | 3 | 1 | 0 | 2
| RESEARCH | 5 | 1 | 0 | 2
| SALES | 6 | 1 | 0 | 2
| | 17 | 1 | 1 | 3
(12 rows)
下表提供了 GROUPING_ID 函数计算的特定示例,该计算基于输出四行的 GROUPING 函数返回值。
loc | dname | Bit Vector
gf_loc gf_dname |
GROUPING_ID
gid |
---|---|---|---|
BOSTON | OPERATIONS | 0 * 2 1+ 0 * 20 | 0 |
BOSTON | null | 0 * 2 1+ 1 * 20 | 1 |
null | ACCOUNTING | 1 * 2 1+ 0 * 20 | 2 |
null | null | 1 * 2 1+ 1 * 20 | 3 |
下表概述了 GROUPING_ID 函数返回值与对其执行聚合的分组列的对应关系。
Aggregation by Column | Bit Vector
gf_loc gf_dname |
GROUPING_ID
gid |
---|---|---|
loc, dname | 0 0 | 0 |
loc | 0 1 | 1 |
dname | 1 0 | 2 |
Grand Total | 1 1 | 3 |
因此,要只按 dname 显示这些小计,可通过基于 GROUPING_ID 函数的 HAVING 子句使用以下简化查询。
SELECT loc, dname, COUNT(*) AS "employees",
GROUPING(loc) AS "gf_loc", GROUPING(dname) AS "gf_dname",
GROUPING_ID(loc, dname) AS "gid"
FROM emp e, dept d
WHERE e.deptno = d.deptno
GROUP BY CUBE (loc, dname)
HAVING GROUPING_ID(loc, dname) = 2
ORDER BY 6, 1, 2;
下面是该查询的结果。
loc | dname | employees | gf_loc | gf_dname | gid
-----+------------+-----------+--------+----------+-----
| ACCOUNTING | 3 | 1 | 0 | 2
| OPERATIONS | 3 | 1 | 0 | 2
| RESEARCH | 5 | 1 | 0 | 2
| SALES | 6 | 1 | 0 | 2
(4 rows)