分组子句
GROUP BY 子句指定由 R 行分组组成的中间结果表。 R 是子查询的前一个子句的结果。
GROUP BY 子句最简单的格式包含 分组表达式。 分组表达式是用于定义 R 的分组的 表达式 。 分组表达式中包含的每个 表达式或 列名 必须明确标识 R 的列 (SQLSTATE 42702 或 42703)。 分组表达式不能包含标量全查询 , XMLQUERY 或 XMLEXISTS 表达式 (SQLSTATE 42822) ,也不能包含 非确定性 或具有外部操作 (SQLSTATE 42845) 的任何 表达式或 函数。
- table-designator 的行更改时间戳记
- table-designator 的行更改标记
- RID_BIT 或 RID 标量函数
GROUP BY 子句的更复杂格式包括 分组集 和 超组。 有关 分组集的描述,请参阅 分组集。 有关 超组的描述,请参阅 超组。
GROUP BY 的结果是一组行。 此结果中的每一行都表示 分组表达式 相等的一组行。 对于分组, 分组表达式 中的所有空值都被视为相等。
如果 分组表达式 包含十进制浮点列,并且这些列中存在多个相同数字的表示,那么返回的数字可以是该数字的任何表示。
可以在 HAVING 子句中的搜索条件, SELECT 子句中的表达式或 ORDER BY 子句的 sort-key-expression 中使用 分组表达式 (请参阅 order-by-clause 以获取详细信息)。 在每种情况下,引用仅为每个组指定一个值。 例如,如果 分组表达式 为 col1+col2,那么 SELECT 列表中允许的表达式为 col1+col2+3。 表达式的关联性规则不允许类似的表达式 3+col1+col2,除非使用括号来确保以相同的顺序对相应的表达式求值。 因此,在 SELECT 列表中也允许 3 + (col1+col2) 。 如果使用并置运算符,那么 分组表达式 必须与 SELECT 列表中指定的表达式完全相同。
如果 分组表达式 包含带有尾部空格的变长字符串,那么组中的值在尾部空格的数目上可能有所不同,并且可能并非所有值都具有相同的长度。 在这种情况下,对 分组表达式 的引用仍然为每个组指定一个值。 但是,组的值是从可用值集合中任意选择的,或者是从可用值集合中任意选择的规范化格式。 因此,结果值的实际长度不可预测。
如前所述,在某些情况下, GROUP BY 子句无法将 SELECT 子句中指定的列作为表达式 (scalar-fullselect , 非确定性 或外部操作函数) 直接引用。 要使用此类表达式进行分组,请使用嵌套表表达式或公共表表达式来首先提供将表达式作为结果列的结果表。 有关使用嵌套表表达式的示例,请参阅 子查询示例中的 示例 9 。
分组集
分组集 规范可用于在单个语句中指定多个分组子句。 这可以被认为是将两组或多组行联合到单个结果集中。 它在逻辑上等同于在对应于一个分组集的每个子选择中使用 group by 子句的多个子选择的并集。 分组集可以是单个元素,也可以是由括号定界的元素列表,其中元素是分组表达式或超组。 可以使用 分组集通过对基本表的单次传递来计算组。
分组集 规范支持简单的 分组表达式 或更复杂的 超组 格式。 有关 超组的描述,请参阅 超组。
GROUP BY a等同于 GROUP BY GROUPING SETS((a))及 GROUP BY a,b,c等同于 GROUP BY GROUPING SETS((a,b,c))从分组集中排除的子查询的 SELECT 列表中的非聚集列将针对为该分组集生成的每行返回一个空值。 这反映了在不考虑这些列的值的情况下执行聚集的事实。
在 示例 2 到 分组集,多维数据集和累积查询的示例中的 示例 7 中说明了如何使用分组集。
超组
- 1 Alternate specification when used alone in group-by-clause is: grouping-expression-list WITH ROLLUP.
- 2 Alternate specification when used alone in group-by-clause is: grouping-expression-list WITH CUBE.
- ROLLUP ( 分组表达式列表 )
- ROLLUP 分组 是 GROUP BY 子句的扩展,它除了生成
常规
分组行外,还生成包含 小计 行的结果集。 小计 行是超级聚集
行,其中包含通过应用用于获取分组行的相同聚集函数来派生其值的进一步聚集。 这些行称为小计行,因为这是它们最常用的行; 但是,任何聚集函数都可以用于聚集。 例如, MAX 和 AVG 在 分组集,多维数据集和累积查询的示例中的 示例 8 中使用。 GROUP 聚集函数可用于指示超组是否生成了行。ROLLUP 分组是一系列 分组集。 具有 n 元素的 ROLLUP 的常规规范
相当于:GROUP BY ROLLUP(C1,C2,...,Cn-1,Cn)GROUP BY GROUPING SETS((C1,C2,...,Cn-1,Cn) (C1,C2,...,Cn-1) ... (C1,C2) (C1) () )请注意, ROLLUP 的 n 元素会转换为 n+ 1 分组集。 另请注意,指定 分组表达式 的顺序对于 ROLLUP 很重要。 例如,以下子句:
相当于:GROUP BY ROLLUP(a,b)
同样,以下条款:GROUP BY GROUPING SETS((a,b) (a) () )
相当于:GROUP BY ROLLUP(b,a)GROUP BY GROUPING SETS((b,a) (b) () )ORDER BY 子句是保证结果集中行的顺序的唯一方法。 分组集,多维数据集和累积查询的示例 中的 示例 3 说明了 ROLLUP 的使用。
- CUBE ( 分组表达式列表 )
- CUBE 分组 是 GROUP BY 子句的扩展,用于生成包含 ROLLUP 聚集的所有行的结果集,此外还包含 "交叉制表" 行。 交叉制表 行是其他 "超聚合" 行,它们不是具有小计的聚合的一部分。 GROUP 聚集函数可用于指示是否由超组生成了行。 与 ROLLUP 类似, CUBE 分组也可以视为一系列 分组集。 对于 CUBE ,将计算多维数据集 分组表达式列表 的所有排列以及总计。 因此, CUBE 的 n 元素转换为 2 * *n (2 到电源 n) 分组集。 例如,规范:
GROUP BY CUBE(a,b,c)相当于:
GROUP BY GROUPING SETS((a,b,c) (a,b) (a,c) (b,c) (a) (b) (c) () )请注意, CUBE 的三个元素会转换为八个分组集。
元素的指定顺序对于 CUBE 无关紧要。 "CUBE (DayOfYear , Sales_Person)" 和 "CUBE (Sales_Person , DayOfYear)" 生成相同的结果集。 "相同" 一词的使用适用于结果集的内容,而不是其顺序。 ORDER BY 子句是保证结果集中行的顺序的唯一方法。 在 分组集,多维数据集和累积查询的示例中的 示例 4 中说明了如何使用 CUBE。
- 分组表达式列表
- 分组表达式列表 在 CUBE 或 ROLLUP 子句中用于定义 CUBE 或 ROLLUP 操作中的元素数。 这通过使用括号对具有多个 分组表达式的元素进行定界来控制。
例如,假设查询将返回省内但不在县内的城市 ROLLUP 的总费用。 但是,该条款:
GROUP BY ROLLUP(Province, County, City)导致针对县的不需要的小计行。 在该条款中:
GROUP BY ROLLUP(Province, (County, City))组合 (County , City) 构成 ROLLUP 中的一个元素,因此,使用此子句的查询将生成所需的结果。 换句话说,两要素 ROLLUP:
GROUP BY ROLLUP(Province, (County, City))生成:
GROUP BY GROUPING SETS((Province, County, City) (Province) () )三元素 ROLLUP 生成:
GROUP BY GROUPING SETS((Province, County, City) (Province, County) (Province) () )分组集,多维数据集和累积查询的示例 中的 示例 2 也使用组合列值。
- 总计
- CUBE 和 ROLLUP 都返回一行,即整体 (总计) 聚集。 这可以在分组 SET 子句中使用空括号单独指定。 它也可以直接在 GROUP BY 子句中指定,尽管对查询的结果没有影响。 分组集,多维数据集和累积查询的示例 中的 示例 4 使用总计语法。
组合分组集
这可用于组合任何类型的 GROUP BY 子句。 当简单的 分组表达式 字段与其他组组合时,它们将 "附加" 到生成的 分组集的开头。 当 ROLLUP 或 CUBE 表达式组合时,它们与剩余表达式上的 "乘数" 操作相似,根据 ROLLUP 或 CUBE 的定义形成额外的分组集条目。
GROUP BY a, ROLLUP(b,c)相当于: GROUP BY GROUPING SETS((a,b,c)
(a,b)
(a) )或者类似的 GROUP BY a, b, ROLLUP(c,d)相当于: GROUP BY GROUPING SETS((a,b,c,d)
(a,b,c)
(a,b) )ROLLUP 元素的组合如下所示: GROUP BY ROLLUP(a), ROLLUP(b,c)相当于:
GROUP BY GROUPING SETS((a,b,c)
(a,b)
(a)
(b,c)
(b)
() ) 类似的示例,
GROUP BY ROLLUP(a), CUBE(b,c) 相当于:
GROUP BY GROUPING SETS((a,b,c)
(a,b)
(a,c)
(a)
(b,c)
(b)
(c)
() ) CUBE 和 ROLLUP 元素的组合如下所示:
GROUP BY CUBE(a,b), ROLLUP(c,d) 相当于:
GROUP BY GROUPING SETS((a,b,c,d)
(a,b,c)
(a,b)
(a,c,d)
(a,c)
(a)
(b,c,d)
(b,c)
(b)
(c,d)
(c)
() ) GROUP BY a, ROLLUP(a,b)相当于: GROUP BY GROUPING SETS((a,b)
(a) )组合分组集的一个更完整的示例是构造一个结果集,以消除可能针对完整 CUBE 聚集返回的某些行。
GROUP BY Region,
ROLLUP(Sales_Person, WEEK(Sales_Date)),
CUBE(YEAR(Sales_Date), MONTH (Sales_Date))将对 GROUP BY 右侧的列进行分组,汇总 ROLLUP 后括号内的列,以及 CUBE 后括号内的列。 因此, GROUP BY 子句会在 YEAR 中生成 MONTH 的多维数据集,然后在 "区域" 聚集中的 Sales_Person 内的 WEEK 中汇总该多维数据集。 它不会在 Region , Sales_Person 或 WEEK (Sales_Date) 上生成任何总计行或任何交叉制表行,因此生成的行少于子句:
GROUP BY ROLLUP (Region, Sales_Person, WEEK(Sales_Date),
YEAR(Sales_Date), MONTH(Sales_Date) )