文档文档

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 标签

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

GROUP BY 标签示例

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

按单个标签对数据进行分组

按多个标签对数据进行分组

按所有标签对数据进行分组

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

GROUP BY 时间

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 时间并填充空白

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

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

  • 数字字面量:将 null 值替换为指定的数字字面量。
  • 线性:使用现有值之间的线性插值来替换 null 值。
  • :删除包含 null 字段值的行。
  • null:保留 null 值和关联的时间戳。
  • 先前值:将 null 值替换为最近的非 null 值。

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

GROUP BY 时间示例

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

将分组和聚合查询结果放入 1 小时窗口

按标签将分组和聚合查询结果放入 1 周间隔

GROUP BY 时间和偏移量

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

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

GROUP BY 时间并填充空白

将分组和聚合查询结果放入 30 分钟间隔,并用 0 填充空白

将分组和聚合查询结果放入 30 分钟间隔,并使用线性插值填充空白

将分组和聚合查询结果放入 30 分钟间隔,并用先前值填充空白

结果集

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

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

默认时间范围

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

SELECT mean(temp) FROM home GROUP BY room

name: home
tags: room=Kitchen

time平均值
1970-01-01T00:00:00Z22.623076923076926

name: home
tags: room=Living Room

time平均值
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 值。


此页是否对您有帮助?

感谢您的反馈!


Flux 的未来

Flux 即将进入维护模式。您可以继续像现在一样使用它,而无需对代码进行任何更改。

阅读更多

现已全面上市

InfluxDB 3 Core 和 Enterprise

快速启动。更快扩展。

获取更新

InfluxDB 3 Core 是一个开源、高速、近实时数据引擎,可实时收集和处理数据,并将其持久化到本地磁盘或对象存储。InfluxDB 3 Enterprise 构建在 Core 的基础上,增加了高可用性、读取副本、增强的安全性以及数据压缩,以实现更快的查询和优化的存储。InfluxDB 3 Enterprise 的免费层可供非商业家庭或业余爱好者使用。

有关更多信息,请查看