文档文档

GROUP BY 子句

InfluxDB 3 Core 处于公开 Alpha 阶段

InfluxDB 3 Core 处于公开 alpha 阶段,可用于测试和反馈,但不适用于生产环境。产品和本文档都在不断完善中。我们欢迎并鼓励您提供关于 alpha 体验的意见,并邀请您加入我们的公共频道以获取更新和分享反馈。

Alpha 预期和建议

使用 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

名称: home
标签: room=Kitchen

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

名称: home
标签: room=Living Room

时间平均值
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)

注意:查询结果数据的第一行中的时间戳发生在查询时间范围开始之前。查看原因

示例数据

时间字段
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

查询结果

时间字段
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 开源版本现已公开 Alpha

InfluxDB 3 开源版本现已可用于 alpha 测试,根据 MIT 或 Apache 2 许可获得许可。

我们正在发布两个产品作为 alpha 版本的一部分。

InfluxDB 3 Core 是我们的全新开源产品。它是一个用于时间序列和事件数据的最新数据引擎。InfluxDB 3 Enterprise 是一个商业版本,它建立在 Core 的基础上,增加了历史查询能力、读取副本、高可用性、可扩展性和细粒度的安全性。

有关如何开始使用的更多信息,请查看