文档文档

GROUP BY 子句

使用 GROUP BY 子句,按一个或多个指定的 标签 或指定的时间间隔对数据进行分组。GROUP BY 要求 SELECT 语句中包含 聚合选择器 函数。

语法

SELECT_clause FROM_clause [WHERE_clause] GROUP BY group_expression[, ..., group_expression_n]

GROUP BY 子句的行为

  • GROUP BY tag_key - 按特定标签对数据进行分组
  • GROUP BY tag_key1, tag_key2 - 按多个标签对数据进行分组
  • GROUP BY * - 按所有 标签 对数据进行分组
  • GROUP BY /regex/ - 按匹配正则表达式的标签键对数据进行分组
  • GROUP BY time() - 将数据分组为时间间隔(窗口)

如果查询包含 WHEREGROUP BY,则 GROUP BY 子句必须出现在 WHERE 子句之后。

按标签分组 (GROUP BY tags)

按一个或多个标签列对数据进行分组。

按标签分组示例 (GROUP BY tags examples)

以下示例使用 比特币价格示例数据

将数据按单个标签分组

将数据按多个标签分组

将数据按所有标签分组

按匹配正则表达式的标签键对数据进行分组

按时间分组 (GROUP BY time)

GROUP BY time() 按指定的时间间隔(也称为“窗口”)将数据分组,并对每个时间间隔应用 SELECT 子句中的 聚合选择器 函数。使用 time() 函数 指定要分组的时间间隔。

SELECT_clause FROM_clause WHERE <time_range> GROUP BY time(time_interval[, offset])[, group_expression (...)] [fill(behavior)]

GROUP BY time() 间隔使用预设的整数时间边界,这些边界独立于 WHERE 子句 中的时间条件。输出数据使用窗口开始边界作为聚合时间戳。使用 time() 函数的 offset 参数向前或向后移动时间边界。

按时间分组并填充空缺 (GROUP by time and fill gaps)

按时间分组时,如果查询时间范围内某个窗口不包含数据,结果将返回该空窗口的一行,其中包含空窗口的时间戳以及每个查询字段的 null 值。使用 fill() 函数放在 GROUP BY 子句的末尾 来替换 null 字段值。如果未包含 FILL 子句,则默认行为是 fill(null)

fill() 为填充值提供以下行为

  • numeric literal:用指定数值常量替换 null 值。
  • linear:使用现有值之间的线性插值来替换 null 值。
  • none:删除带有 null 字段值的行。
  • null:保留 null 值和相关时间戳。
  • previous:用最近的非 null 值替换 null 值。

有关详细示例,请参阅 fill() 文档

按时间分组示例

以下示例使用 比特币价格示例数据

将查询结果分组并聚合到 1 小时窗口中

按标签将查询结果分组并聚合到 1 周时间间隔中

按时间分组并带偏移量

将查询结果分组并聚合到 1 小时时间间隔中,并将时间边界偏移 +15 分钟

将查询结果分组并聚合到 1 小时时间间隔中,并将时间边界偏移 -15 分钟

按时间分组并填充空缺

将查询结果分组并聚合到 30 分钟间隔中,并用 0 填充空缺

将查询结果分组并聚合到 30 分钟间隔中,并使用线性插值填充空缺

将查询结果分组并聚合到 30 分钟间隔中,并用前值填充空缺

结果集

如果查询至少有一行满足条件,InfluxDB 3 Core 将在查询结果集中返回行数据。如果查询使用 GROUP BY 子句,结果集将包含以下内容:

  • 查询 SELECT 子句中列出的列
  • 一个 time 列,其中包含记录或组的时间戳
  • 一个 iox::measurement 列,其中包含记录的测量(表)名称
  • 查询 GROUP BY 子句中列出的列;结果集中的每一行都包含用于分组的值

默认时间范围

如果查询未在 WHERE 子句 中指定时间范围,InfluxDB 将使用 默认时间范围 进行过滤和按时间分组。如果查询包含 GROUP BY 子句且未在 WHERE 子句中指定时间范围,则默认时间分组为 默认时间范围,并且结果集中的 time 列将包含该范围的开始时间,例如:

SELECT mean(temp) FROM home GROUP BY room

name: home
标签:room=Kitchen

timemean
1970-01-01T00:00:00Z22.623076923076926

name: home
标签:room=Living Room

timemean
1970-01-01T00:00:00Z22.16923076923077

GROUP BY 子句的注意事项

不能按字段分组

InfluxQL 不支持按**字段**对数据进行分组。

标签顺序无关紧要

GROUP BY 子句中列出标签的顺序不会影响数据分组的方式。

按标签分组且无时间范围会返回意外的时间戳

time 列包含 默认时间范围 的开始时间。

按时间分组的数据可能返回意外的时间戳

由于 GROUP BY time() 间隔使用预设的整数时间边界,这些边界与 WHERE 子句 中的时间条件无关,因此结果可能包含超出查询时间范围的时间戳。结果仅表示时间戳在指定时间范围内的对应数据,但输出时间戳由预设时间边界确定。

以下示例按 1 小时间隔对数据进行分组,但 WHERE 子句定义的时间范围仅涵盖一个窗口的一部分

SELECT MEAN(field)
FROM example 
WHERE
  time >= '2022-01-01T00:30:00Z'
  AND time <= '2022-01-01T01:30:00Z'
GROUP BY time(1h)

注意:查询结果数据的第一行中的时间戳出现在查询时间范围的开始时间之前。 原因见此

示例数据

time字段
2022-01-01T00:00:00Z8
2022-01-01T00:15:00Z4
2022-01-01T00:30:00Z0
2022-01-01T00:45:00Z8
2022-01-01T01:00:00Z5
2022-01-01T01:15:00Z0
2022-01-01T01:30:00Z8
2022-01-01T01:45:00Z8
2022-01-01T02:00:00Z9
2022-01-01T02:15:00Z6
2022-01-01T02:30:00Z3
2022-01-01T02:45:00Z0

查询结果

time字段
2022-01-01T00:00:00Z4
2022-01-01T01:00:00Z5.25
2022-01-01T02:00:00Z6

为什么这些结果包含超出查询时间范围的时间戳?

查询时间范围内无数据时的填充

如果查询时间范围内没有数据,查询将忽略 fill()。这是预期行为。

无前值时的填充

如果查询时间范围内没有前值,fill(previous) 将不会填充 null 值。

插值时不足两个值时的填充

如果查询时间范围内,null 值之前或之后都没有值,fill(linear) 将不会填充 null 值。


此页面是否有帮助?

感谢您的反馈!


InfluxDB 3.8 新特性

InfluxDB 3.8 和 InfluxDB 3 Explorer 1.6 的主要增强功能。

查看博客文章

InfluxDB 3.8 现已适用于 Core 和 Enterprise 版本,同时发布了 InfluxDB 3 Explorer UI 的 1.6 版本。本次发布着重于操作成熟度,以及如何更轻松地部署、管理和可靠地运行 InfluxDB。

更多信息,请查看

InfluxDB Docker 的 latest 标签将指向 InfluxDB 3 Core

在 **2026 年 2 月 3 日**,InfluxDB Docker 镜像的 latest 标签将指向 InfluxDB 3 Core。为避免意外升级,请在您的 Docker 部署中使用特定的版本标签。

如果使用 Docker 来安装和运行 InfluxDB,latest 标签将指向 InfluxDB 3 Core。为避免意外升级,请在您的 Docker 部署中使用特定的版本标签。例如,如果使用 Docker 运行 InfluxDB v2,请将 latest 版本标签替换为 Docker pull 命令中的特定版本标签 — 例如

docker pull influxdb:2