GROUP BY 子句
InfluxDB 3 Core 处于公开 Alpha 阶段
InfluxDB 3 Core 处于公开 alpha 阶段,可用于测试和反馈,但不适用于生产环境。产品和本文档都在不断完善中。我们欢迎并鼓励您提供关于 alpha 体验的意见,并邀请您加入我们的公共频道以获取更新和分享反馈。
Alpha 预期和建议
- 在 alpha 期间,我们可能会进行破坏性更改,可能需要您删除数据并重新开始。如果您使用的数据很重要,请在其他地方保留备份副本。
- 在 alpha 期间,我们会在每次合并到 InfluxDB
main
分支时生成新的构建版本。更改频繁,相关更新会发布到我们的公共频道。
使用 GROUP BY
子句按一个或多个指定的标签或按指定的时间间隔对数据进行分组。GROUP BY
需要在 SELECT
语句中使用聚合或选择器函数。
语法
SELECT_clause FROM_clause [WHERE_clause] GROUP BY group_expression[, ..., group_expression_n]
- group_expression: 用于标识要分组的标签或时间间隔的表达式。可以是标签键、常量、正则表达式、通配符 (
*
) 或函数表达式。
GROUP BY 子句行为
GROUP BY tag_key
- 按特定标签分组数据GROUP BY tag_key1, tag_key2
- 按多个标签分组数据GROUP BY *
- 按所有标签分组数据GROUP BY /regex/
- 按与正则表达式匹配的标签键分组数据GROUP BY time()
- 将数据分组到时间间隔(窗口)中
如果查询包含 WHERE
和 GROUP BY
,则 GROUP BY
子句必须出现在 WHERE
子句之后。
按一个或多个标签列分组数据。
以下示例使用比特币价格示例数据。
按单个标签分组数据
SELECT MEAN(*) FROM bitcoin GROUP BY code
时间 | 平均价格 |
---|
1970-01-01T00:00:00Z | 27328.848667840004 |
时间 | 平均价格 |
---|
1970-01-01T00:00:00Z | 23441.832453919982 |
时间 | 平均价格 |
---|
1970-01-01T00:00:00Z | 28054.160950480004 |
按多个标签分组数据
SELECT MEAN(*) FROM bitcoin GROUP BY code, description
时间 | 平均价格 |
---|
1970-01-01T00:00:00Z | 27328.848667840004 |
时间 | 平均价格 |
---|
1970-01-01T00:00:00Z | 23441.832453919982 |
时间 | 平均价格 |
---|
1970-01-01T00:00:00Z | 28054.160950480004 |
按与正则表达式匹配的标签键分组数据
SELECT MEAN(*) FROM bitcoin GROUP BY /^[cd]/
时间 | 平均价格 |
---|
1970-01-01T00:00:00Z | 27328.848667840004 |
时间 | 平均价格 |
---|
1970-01-01T00:00:00Z | 23441.832453919982 |
时间 | 平均价格 |
---|
1970-01-01T00:00:00Z | 28054.160950480004 |
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 小时窗口中
SELECT
MEAN(price)
FROM bitcoin
WHERE
code = 'USD'
AND time >= '2023-05-01T00:00:00Z'
AND time < '2023-05-15T00:00:00Z'
GROUP BY time(1h)
时间 | 平均值 |
---|
2023-05-01T00:00:00Z | 24494.27265 |
2023-05-01T01:00:00Z | 24452.1698 |
2023-05-01T02:00:00Z | 23902.666124999996 |
2023-05-01T03:00:00Z | 23875.211349999998 |
2023-05-01T04:00:00Z | 23855.6441 |
… | … |
按标签将查询结果分组并聚合到 1 周间隔
SELECT
MEAN(price)
FROM bitcoin
WHERE
time >= '2023-05-01T00:00:00Z'
AND time < '2023-05-15T00:00:00Z'
GROUP BY time(1w), code
时间 | 平均值 |
---|
2023-04-27T00:00:00Z | 27681.21808576779 |
2023-05-04T00:00:00Z | 27829.413580354256 |
2023-05-11T00:00:00Z | 26210.24799033149 |
时间 | 平均值 |
---|
2023-04-27T00:00:00Z | 23744.083925842704 |
2023-05-04T00:00:00Z | 23871.201395652173 |
2023-05-11T00:00:00Z | 22482.33174723755 |
时间 | 平均值 |
---|
2023-04-27T00:00:00Z | 28415.88231123595 |
2023-05-04T00:00:00Z | 28568.010941384844 |
2023-05-11T00:00:00Z | 26905.87242099449 |
GROUP BY 带偏移时间
将查询结果分组并聚合到 1 小时间隔,并将时间边界偏移 +15 分钟
SELECT
MEAN(price)
FROM bitcoin
WHERE
code = 'USD'
AND time >= '2023-05-01T00:00:00Z'
AND time < '2023-05-02T00:00:00Z'
GROUP BY time(1h, 15m)
时间 | 平均值 |
---|
2023-04-30T23:15:00Z | |
2023-05-01T00:15:00Z | 29313.6754 |
2023-05-01T01:15:00Z | 28932.0882 |
2023-05-01T02:15:00Z | 28596.375225000003 |
2023-05-01T03:15:00Z | 28578.915075 |
… | … |
请注意,offset
强制第一个时间边界超出查询的时间范围,因此查询不会返回第一个间隔的结果。
将查询结果分组并聚合到 1 小时间隔,并将时间边界偏移 -15 分钟
SELECT
MEAN(price)
FROM bitcoin
WHERE
code = 'USD'
AND time >= '2023-05-01T00:00:00Z'
AND time < '2023-05-02T00:00:00Z'
GROUP BY time(1h, -15m)
时间 | 平均值 |
---|
2023-04-30T23:45:00Z | 29319.9092 |
2023-05-01T00:45:00Z | 29285.3651 |
2023-05-01T01:45:00Z | 28607.202666666668 |
2023-05-01T02:45:00Z | 28576.056175 |
2023-05-01T03:45:00Z | 28566.96315 |
… | … |
GROUP BY 时间并填充间隙
将查询结果分组并聚合到 30 分钟间隔,并用 0
填充间隙
SELECT
MEAN(price)
FROM bitcoin
WHERE
code = 'USD'
AND time >= '2023-05-01T00:00:00Z'
AND time < '2023-05-01T02:00:00Z'
GROUP BY
time(30m)
fill(0)
时间 | 平均值 |
---|
2023-05-01T00:00:00Z | 29319.9092 |
2023-05-01T00:30:00Z | 29307.4416 |
2023-05-01T01:00:00Z | 0 |
2023-05-01T01:30:00Z | 29263.2886 |
将查询结果分组并聚合到 30 分钟间隔,并使用线性插值填充间隙
SELECT
MEAN(price)
FROM bitcoin
WHERE
code = 'USD'
AND time >= '2023-05-01T00:00:00Z'
AND time < '2023-05-01T02:00:00Z'
GROUP BY
time(30m)
fill(linear)
时间 | 平均值 |
---|
2023-05-01T00:00:00Z | 29319.9092 |
2023-05-01T00:30:00Z | 29307.4416 |
2023-05-01T01:00:00Z | 29285.3651 |
2023-05-01T01:30:00Z | 29263.2886 |
将查询结果分组并聚合到 30 分钟间隔,并用先前的值填充间隙
SELECT
MEAN(price)
FROM bitcoin
WHERE
code = 'USD'
AND time >= '2023-05-01T00:00:00Z'
AND time < '2023-05-01T02:00:00Z'
GROUP BY
time(30m)
fill(previous)
时间 | 平均值 |
---|
2023-05-01T00:00:00Z | 29319.9092 |
2023-05-01T00:30:00Z | 29307.4416 |
2023-05-01T01:00:00Z | 29307.4416 |
2023-05-01T01:30:00Z | 29263.2886 |
结果集
如果至少有一行满足查询条件,则 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
时间 | 平均值 |
---|
1970-01-01T00:00:00Z | 22.623076923076926 |
时间 | 平均值 |
---|
1970-01-01T00:00:00Z | 22.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:00Z | 8 |
2022-01-01T00:15:00Z | 4 |
2022-01-01T00:30:00Z | 0 |
2022-01-01T00:45:00Z | 8 |
2022-01-01T01:00:00Z | 5 |
2022-01-01T01:15:00Z | 0 |
2022-01-01T01:30:00Z | 8 |
2022-01-01T01:45:00Z | 8 |
2022-01-01T02:00:00Z | 9 |
2022-01-01T02:15:00Z | 6 |
2022-01-01T02:30:00Z | 3 |
2022-01-01T02:45:00Z | 0 |
查询结果
时间 | 字段 |
---|
2022-01-01T00:00:00Z | 4 |
2022-01-01T01:00:00Z | 5.25 |
2022-01-01T02:00:00Z | 6 |
为什么这些结果包含查询时间范围之外的时间戳?
GROUP BY time()
基于指定的时间间隔创建具有预定义时间边界的窗口。这些边界不是由查询的时间范围决定的,但是,查询结果中的聚合值仅使用查询时间范围内的值计算。
时间 | 字段 |
---|
2022-01-01T00:00:00Z | 8 |
2022-01-01T00:15:00Z | 4 |
2022-01-01T00:30:00Z | 0 |
2022-01-01T00:45:00Z | 8 |
2022-01-01T01:00:00Z | 5 |
2022-01-01T01:15:00Z | 0 |
2022-01-01T01:30:00Z | 8 |
2022-01-01T01:45:00Z | 8 |
2022-01-01T02:00:00Z | 9 |
2022-01-01T02:15:00Z | 6 |
2022-01-01T02:30:00Z | 3 |
2022-01-01T02:45:00Z | 0 |
在查询的时间范围内用无数据填充
如果查询的时间范围内没有数据,则查询会忽略 fill()
。这是预期行为。
如果没有先前的值,则用先前的值填充
如果查询的时间范围内没有先前的值,则 fill(previous)
不会填充 null 值。
如果不存在两个值用于插值,则使用线性插值填充
如果在查询的时间范围内 null 值之前或之后没有值,则 fill(linear)
不会填充 null 值。
支持和反馈
感谢您成为我们社区的一份子!我们欢迎并鼓励您提供关于 InfluxDB 3 Core 和本文档的反馈和错误报告。要获得支持,请使用以下资源
拥有年度或支持合同的客户可以联系 InfluxData 支持。