可用版本: Dev (3.21) | 最新 (3.20) | 3.19 | 3.18 | 3.17 | 3.16 | 3.15 | 3.14 | 3.13 | 3.12 | 3.11

分组

适用于 ✅ 开源版   ✅ 专业版   ✅ 企业版

聚合函数将来自数据组的数据聚合为单个值。形成这些组主要有三种方式

  • GROUP BY 子句用于定义聚合数据的组
  • 未定义 GROUP BY 子句,这意味着来自 SELECT 语句(或子查询)的所有数据都聚合到单行中
  • 所有聚合函数都可以用作窗口函数,在这种情况下,它们将聚合指定窗口的数据

使用 GROUP BY 进行聚合

在存在 GROUP BY 的情况下,SELECT 语句将其 FROM 子句 的输出转换为包含以下内容的新“虚拟”元组集

  • GROUP BY 子句的列表达式。 在整个数据集中,这些列表达式的值是唯一的。
  • 对应于 GROUP BY 子句生成的每一行的数据集。 可以使用聚合函数按组聚合此数据集。

使用 GROUP BY 意味着需要在查询的其余部分中遵守一组新的规则

一个例子

SELECT AUTHOR_ID, count(*)
FROM BOOK
GROUP BY AUTHOR_ID;
create.select(BOOK.AUTHOR_ID, count())
      .from(BOOK)
      .groupBy(BOOK.AUTHOR_ID).fetch();

产生

+-----------+-------+
| AUTHOR_ID | count |
+-----------+-------+
|         1 |     2 |
|         2 |     2 |
+-----------+-------+

根据 GROUP BY 施加的规则,例如,不可能投影 BOOK.TITLE 列,因为它不是按作者定义的。 一位作者写了很多书,所以我们不知道 BOOK.TITLE 应该意味着什么。 只有聚合,例如 LISTAGGARRAY_AGG 可以引用 BOOK.TITLE 作为参数。

不使用 GROUP BY 进行聚合

在没有 GROUP BY 的情况下,SELECT 语句的任何子句(例如 HAVINGWINDOWSELECTORDER BY)中包含至少一个聚合函数,则会将整个数据聚合到单行中。 有一个隐含的“空分组”,即没有 GROUP BY 列的分组。 这两个是同一件事

SELECT count(*) FROM BOOK;
SELECT count(*) FROM BOOK GROUP BY ();

有关此空 GROUP BY 语法的更多详细信息,另请参见 GROUPING SETS

例如,使用我们的示例数据库,其中包含 4 本 ID 为 1-4 的书籍,我们可以编写

SELECT count(*), sum(ID)
FROM BOOK
create.select(count(), sum(BOOK.ID))
      .from(BOOK).fetch();

产生

+----------+---------+
| count(*) | sum(ID) |
+----------+---------+
|        4 |      10 |
+----------+---------+

FROM 子句中表中的其他任何列都不能被 SELECT 子句投影,因为它们没有为此单个组定义。 例如,未为所有书籍的聚合值定义特定的 BOOK.TITLE。 只有聚合,例如 LISTAGGARRAY_AGG 可以引用 BOOK.TITLE 作为参数。

但是,允许使用任何组件不依赖于组内容的表达式。 例如,可以像这样组合聚合函数和常量表达式

SELECT count(*) + sum(ID) + 1
FROM BOOK
create.select(count().plus(sum(BOOK.ID)).plus(1))
      .from(BOOK).fetch();

产生

+------+
| plus |
+------+
|   15 |
+------+

反馈

您对此页面有任何反馈吗? 我们很乐意听到!

The jOOQ Logo