GROUP BY 子句
使用 GROUP BY
子句按一个或多个指定的标签和/或指定的时间间隔对查询结果进行分组。GROUP BY
需要在 SELECT
语句中使用聚合或选择器函数。GROUP BY
支持正则表达式。
注意: 您不能使用 GROUP BY
对字段进行分组。
GROUP BY 标签
GROUP BY <tag>
按一个或多个指定的标签对查询结果进行分组。
语法
SELECT_clause FROM_clause [WHERE_clause] GROUP BY [* | <tag_key>[,<tag_key>]]
GROUP BY *
- 按所有标签分组结果GROUP BY <tag_key>
- 按特定标签分组结果GROUP BY <tag_key>,<tag_key>
- 按多个标签分组结果。标签键的顺序无关紧要。GROUP BY \regex\
- 按与正则表达式匹配的标签分组结果。
如果查询包含 WHERE
子句,则 GROUP BY
子句必须出现在 WHERE
子句之后。
示例
GROUP BY 时间间隔
GROUP BY time()
按用户指定的时间间隔对查询结果进行分组。当在 SELECT
子句中使用聚合或选择器函数时,该操作将应用于每个时间间隔。
基本 GROUP BY time() 语法
语法
SELECT <function>(<field_key>) FROM_clause WHERE <time_range> GROUP BY time(<time_interval>),[tag_key] [fill(<fill_option>)]
基本 GROUP BY time()
查询需要在 SELECT
子句中使用 InfluxQL 函数,并在 WHERE
子句中使用时间范围。请注意,GROUP BY
子句必须位于 WHERE
子句之后。
time(time_interval)
GROUP BY time()
子句中的 time_interval
是一个持续时间字面量。它确定 InfluxDB 如何按时间对查询结果进行分组。例如,time_interval
为 5m
会将查询结果分组为 WHERE
子句中指定的时间范围内的五分钟时间组。
fill(<fill_option>)
fill(<fill_option>)
是可选的。它更改了没有数据的时间间隔报告的值。有关更多信息,请参阅GROUP BY 时间间隔和 fill()
。
覆盖范围
基本 GROUP BY time()
查询依赖于 time_interval
和 InfluxDB 的预设时间边界来确定每个时间间隔中包含的原始数据以及查询返回的时间戳。
基本语法示例
以下示例使用示例数据的以下子样本
SELECT "water_level","location" FROM "h2o_feet" WHERE time >= '2019-08-18T00:00:00Z' AND time <= '2019-08-18T00:30:00Z'
输出
time | water_level | location |
---|---|---|
2019-08-18T00:00:00Z | 8.5040000000 | coyote_creek |
2019-08-18T00:00:00Z | 2.3520000000 | santa_monica |
2019-08-18T00:06:00Z | 8.4190000000 | coyote_creek |
2019-08-18T00:06:00Z | 2.3790000000 | santa_monica |
2019-08-18T00:12:00Z | 8.3200000000 | coyote_creek |
2019-08-18T00:12:00Z | 2.3430000000 | santa_monica |
2019-08-18T00:18:00Z | 8.2250000000 | coyote_creek |
2019-08-18T00:18:00Z | 2.3290000000 | santa_monica |
2019-08-18T00:24:00Z | 8.1300000000 | coyote_creek |
2019-08-18T00:24:00Z | 2.2640000000 | santa_monica |
2019-08-18T00:30:00Z | 8.0120000000 | coyote_creek |
2019-08-18T00:30:00Z | 2.2670000000 | santa_monica |
基本语法的常见问题
查询结果中意外的时间戳和值
使用基本语法,InfluxDB 依赖于 GROUP BY time()
间隔和系统的预设时间边界来确定每个时间间隔中包含的原始数据以及查询返回的时间戳。在某些情况下,这可能会导致意外的结果。
示例
原始数据
SELECT "water_level" FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2019-08-18T00:00:00Z' AND time <= '2019-08-18T00:18:00Z'
输出
time | water_level |
---|---|
2019-08-18T00:00:00Z | 8.5040000000 |
2019-08-18T00:06:00Z | 8.4190000000 |
2019-08-18T00:12:00Z | 8.3200000000 |
2019-08-18T00:18:00Z | 8.2250000000 |
查询和结果
以下示例查询了 12 分钟的时间范围,并将结果分组为 12 分钟的时间间隔,但它返回了两个结果
SELECT COUNT("water_level") FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2019-08-18T00:06:00Z' AND time < '2019-08-18T00:18:00Z' GROUP BY time(12m)
输出
time | count |
---|---|
2019-08-18T00:00:00Z | 1.0000000000 |
2019-08-18T00:12:00Z | 1.0000000000 |
注意: 第一行数据中的时间戳发生在查询时间范围开始之前。
解释
InfluxDB 对 GROUP BY
间隔使用预设的舍入数字时间边界,这些边界独立于 WHERE
子句中的任何时间条件。当它计算结果时,所有返回的数据必须在查询的显式时间范围内发生,但 GROUP BY
间隔将基于预设的时间边界。
下表显示了预设时间边界、相关的 GROUP BY time()
间隔、包含的点以及结果中每个 GROUP BY time()
间隔返回的时间戳。
时间间隔编号 | 预设时间边界 | GROUP BY time() 间隔 | 包含的点 | 返回的时间戳 |
---|---|---|---|---|
1 | time >= 2019-08-18T00:00:00Z AND time < 2019-08-18T00:12:00Z | time >= 2019-08-18T00:06:00Z AND time < 2019-08-18T00:12:00Z | 8.005 | 2019-08-18T00:00:00Z |
2 | time >= 2019-08-12T00:12:00Z AND time < 2019-08-18T00:24:00Z | time >= 2019-08-12T00:12:00Z AND time < 2019-08-18T00:18:00Z | 7.887 | 2019-08-18T00:12:00Z |
第一个预设的 12 分钟时间边界从 00:00
开始,到 00:12
之前结束。只有一个原始点 (8.005
) 同时落在查询的第一个 GROUP BY time()
间隔和第一个时间边界内。请注意,虽然返回的时间戳发生在查询时间范围开始之前,但查询结果排除了在查询时间范围之前发生的数据。
第二个预设的 12 分钟时间边界从 00:12
开始,到 00:24
之前结束。只有一个原始点 (7.887
) 同时落在查询的第二个 GROUP BY time()
间隔和第二个时间边界内。
高级 GROUP BY time()
语法允许用户移动 InfluxDB 数据库的预设时间边界的开始时间。它将预设时间边界向前移动六分钟,以便 InfluxDB 返回
输出
time | count |
---|---|
2019-08-18T00:06:00Z | 2 |
高级 GROUP BY time() 语法
语法
SELECT <function>(<field_key>) FROM_clause WHERE <time_range> GROUP BY time(<time_interval>,<offset_interval>),[tag_key] [fill(<fill_option>)]
高级 GROUP BY time()
查询需要在 SELECT
子句中使用 InfluxQL 函数,并在 WHERE
子句中使用时间范围)。请注意,GROUP BY
子句必须位于 WHERE
子句之后。
time(time_interval,offset_interval)
有关 time_interval
的详细信息,请参阅基本 GROUP BY time() 语法。
offset_interval
是一个持续时间字面量。它向前或向后移动 InfluxDB 数据库的预设时间边界。offset_interval
可以是正数或负数。
fill(<fill_option>)
fill(<fill_option>)
是可选的。它更改了没有数据的时间间隔报告的值。有关更多信息,请参阅GROUP BY 时间间隔和 fill()
。
覆盖范围
高级 GROUP BY time()
查询依赖于 time_interval
、offset_interval
和 InfluxDB 数据库的预设时间边界来确定每个时间间隔中包含的原始数据以及查询返回的时间戳。
高级语法的示例
以下示例使用示例数据的以下子样本
SELECT "water_level" FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2019-08-18T00:00:00Z' AND time <= '2019-08-18T00:54:00Z'
输出
time | water_level |
---|---|
2019-08-18T00:00:00Z | 8.5040000000 |
2019-08-18T00:06:00Z | 8.4190000000 |
2019-08-18T00:12:00Z | 8.3200000000 |
2019-08-18T00:18:00Z | 8.2250000000 |
2019-08-18T00:24:00Z | 8.1300000000 |
2019-08-18T00:30:00Z | 8.0120000000 |
2019-08-18T00:36:00Z | 7.8940000000 |
2019-08-18T00:42:00Z | 7.7720000000 |
2019-08-18T00:48:00Z | 7.6380000000 |
2019-08-18T00:54:00Z | 7.5100000000 |
GROUP BY
时间间隔和 fill()
fill()
更改了时间间隔中没有数据时报告的值。
语法
SELECT <function>(<field_key>) FROM_clause WHERE <time_range> GROUP BY time(time_interval,[<offset_interval>])[,tag_key] [fill(<fill_option>)]
默认情况下,没有数据的 GROUP BY time()
间隔在输出列中报告 null
值。fill()
更改了时间间隔中没有数据时报告的值。请注意,如果您要 GROUP BY
多个内容(例如,标签 和时间间隔),则 fill()
必须放在 GROUP BY
子句的末尾。
fill_option
- 任何数值 - 为没有数据的时间间隔报告给定的数值。
linear
- 为没有数据的时间间隔报告线性插值的结果。none
- 为没有数据的时间间隔不报告时间戳和值。null
- 为没有数据的时间间隔报告 null,但返回时间戳。这与默认行为相同。previous
- 为没有数据的时间间隔报告前一个时间间隔的值。
示例
不使用 fill(100)
SELECT MEAN("index") FROM "h2o_quality" WHERE "location"='santa_monica' AND time >= '2019-08-19T08:42:00Z' AND time <= '2019-08-19T09:30:00Z' GROUP BY time(5m)
输出
time | mean |
---|---|
2019-08-19T08:40:00Z | 68.0000000000 |
2019-08-19T08:45:00Z | 29.0000000000 |
2019-08-19T08:50:00Z | 47.0000000000 |
2019-08-19T08:55:00Z | |
2019-08-19T09:00:00Z | 84.0000000000 |
2019-08-19T09:05:00Z | 0.0000000000 |
2019-08-19T09:10:00Z | 41.0000000000 |
2019-08-19T09:15:00Z | 13.0000000000 |
2019-08-19T09:20:00Z | 9.0000000000 |
2019-08-19T09:25:00Z | |
2019-08-19T09:30:00Z | 6.0000000000 |
使用 fill(100)
SELECT MEAN("index") FROM "h2o_quality" WHERE "location"='santa_monica' AND time >= '2019-08-19T08:42:00Z' AND time <= '2019-08-19T09:30:00Z' GROUP BY time(5m) fill(100)
输出
time | mean |
---|---|
2019-08-19T08:40:00Z | 68.0000000000 |
2019-08-19T08:45:00Z | 29.0000000000 |
2019-08-19T08:50:00Z | 47.0000000000 |
2019-08-19T08:55:00Z | 100.0000000000 |
2019-08-19T09:00:00Z | 84.0000000000 |
2019-08-19T09:05:00Z | 0.0000000000 |
2019-08-19T09:10:00Z | 41.0000000000 |
2019-08-19T09:15:00Z | 13.0000000000 |
2019-08-19T09:20:00Z | 9.0000000000 |
2019-08-19T09:25:00Z | 100.0000000000 |
2019-08-19T09:30:00Z | 6.0000000000 |
fill(100)
将没有数据的时间间隔报告的值更改为 100
。
不使用 fill(linear)
SELECT MEAN("tadpoles") FROM "pond" WHERE time >= '2019-11-11T21:00:00Z' AND time <= '2019-11-11T22:06:00Z' GROUP BY time(12m)
输出
time | mean |
---|---|
2019-11-11T21:00:00Z | 1 |
2019-11-11T21:12:00Z | |
2019-11-11T21:24:00Z | 3 |
2019-11-11T21:36:00Z | |
2019-11-11T21:48:00Z | |
2019-11-11T22:00:00Z | 6 |
使用 fill(linear)
SELECT MEAN("tadpoles") FROM "pond" WHERE time >= '2019-11-11T21:00:00Z' AND time <= '2019-11-11T22:06:00Z' GROUP BY time(12m) fill(linear)
输出
time | mean |
---|---|
2019-11-11T21:00:00Z | 1 |
2019-11-11T21:12:00Z | 2 |
2019-11-11T21:24:00Z | 3 |
2019-11-11T21:36:00Z | 4 |
2019-11-11T21:48:00Z | 5 |
2019-11-11T22:00:00Z | 6 |
fill(linear)
将没有数据的时间间隔报告的值更改为线性插值的结果。
注意: 此示例中的数据不在 noaa
数据库中。
不使用 fill(none)
SELECT MEAN("index") FROM "h2o_quality" WHERE "location"='santa_monica' AND time >= '2019-08-19T08:42:00Z' AND time <= '2019-08-19T09:30:00Z' GROUP BY time(5m)
输出
time | mean |
---|---|
2019-08-19T08:40:00Z | 68.0000000000 |
019-08-19T08:45:00Z | 29.0000000000 |
2019-08-19T08:50:00Z | 47.0000000000 |
2019-08-19T08:55:00Z | |
2019-08-19T09:00:00Z | 84.0000000000 |
2019-08-19T09:05:00Z | 0.0000000000 |
2019-08-19T09:10:00Z | 41.0000000000 |
2019-08-19T09:15:00Z | 13.0000000000 |
2019-08-19T09:20:00Z | 9.0000000000 |
2019-08-19T09:25:00Z | |
2019-08-19T09:30:00Z | 6.0000000000 |
使用 fill(none)
SELECT MEAN("index") FROM "h2o_quality" WHERE "location"='santa_monica' AND time >= '2019-08-19T08:42:00Z' AND time <= '2019-08-19T09:30:00Z' GROUP BY time(5m) fill(none)
输出
time | mean |
---|---|
2019-08-19T08:40:00Z | 68.0000000000 |
2019-08-19T08:45:00Z | 29.0000000000 |
2019-08-19T08:50:00Z | 47.0000000000 |
2019-08-19T09:00:00Z | 84.0000000000 |
2019-08-19T09:05:00Z | 0.0000000000 |
2019-08-19T09:10:00Z | 41.0000000000 |
2019-08-19T09:15:00Z | 13.0000000000 |
2019-08-19T09:20:00Z | 9.0000000000 |
2019-08-19T09:30:00Z | 6.0000000000 |
`fill(none)` reports no value and no timestamp for the time interval with no data.
不使用 fill(null)
SELECT MEAN("index") FROM "h2o_quality" WHERE "location"='santa_monica' AND time >= '2019-08-19T08:42:00Z' AND time <= '2019-08-19T09:30:00Z' GROUP BY time(5m)
输出
time | mean |
---|---|
2019-08-19T08:40:00Z | 68.0000000000 |
019-08-19T08:45:00Z | 29.0000000000 |
2019-08-19T08:50:00Z | 47.0000000000 |
2019-08-19T08:55:00Z | |
2019-08-19T09:00:00Z | 84.0000000000 |
2019-08-19T09:05:00Z | 0.0000000000 |
2019-08-19T09:10:00Z | 41.0000000000 |
2019-08-19T09:15:00Z | 13.0000000000 |
2019-08-19T09:20:00Z | 9.0000000000 |
2019-08-19T09:25:00Z | |
2019-08-19T09:30:00Z | 6.0000000000 |
使用 fill(null)
SELECT MEAN("index") FROM "h2o_quality" WHERE "location"='santa_monica' AND time >= '2019-08-19T08:42:00Z' AND time <= '2019-08-19T09:30:00Z' GROUP BY time(5m) fill(null)
输出
time | mean |
---|---|
2019-08-19T08:40:00Z | 68.0000000000 |
019-08-19T08:45:00Z | 29.0000000000 |
2019-08-19T08:50:00Z | 47.0000000000 |
2019-08-19T08:55:00Z | null |
2019-08-19T09:00:00Z | 84.0000000000 |
2019-08-19T09:05:00Z | 0.0000000000 |
2019-08-19T09:10:00Z | 41.0000000000 |
2019-08-19T09:15:00Z | 13.0000000000 |
2019-08-19T09:20:00Z | 9.0000000000 |
2019-08-19T09:25:00Z | null |
2019-08-19T09:30:00Z | 6.0000000000 |
fill(null)
将 null
报告为没有数据的时间间隔的值。该结果与不使用 fill(null)
的查询结果匹配。
不使用 fill(previous)
SELECT MEAN("index") FROM "h2o_quality" WHERE "location"='santa_monica' AND time >= '2019-08-19T08:42:00Z' AND time <= '2019-08-19T09:30:00Z' GROUP BY time(5m)
输出
time | mean |
---|---|
2019-08-19T08:40:00Z | 68.0000000000 |
019-08-19T08:45:00Z | 29.0000000000 |
2019-08-19T08:50:00Z | 47.0000000000 |
2019-08-19T08:55:00Z | |
2019-08-19T09:00:00Z | 84.0000000000 |
2019-08-19T09:05:00Z | 0.0000000000 |
2019-08-19T09:10:00Z | 41.0000000000 |
2019-08-19T09:15:00Z | 13.0000000000 |
2019-08-19T09:20:00Z | 9.0000000000 |
2019-08-19T09:25:00Z |
使用 fill(previous)
SELECT MEAN("index") FROM "h2o_quality" WHERE "location"='santa_monica' AND time >= '2019-08-19T08:42:00Z' AND time <= '2019-08-19T09:30:00Z' GROUP BY time(5m) fill(previous)
输出
time | mean |
---|---|
2019-08-19T08:40:00Z | 68.0000000000 |
019-08-19T08:45:00Z | 29.0000000000 |
2019-08-19T08:50:00Z | 47.0000000000 |
2019-08-19T08:55:00Z | 47.0000000000 |
2019-08-19T09:00:00Z | 84.0000000000 |
2019-08-19T09:05:00Z | 0.0000000000 |
2019-08-19T09:10:00Z | 41.0000000000 |
2019-08-19T09:15:00Z | 13.0000000000 |
2019-08-19T09:20:00Z | 9.0000000000 |
2019-08-19T09:25:00Z | 9.0000000000 |
fill(previous)
将没有数据的时间间隔报告的值更改为 3.235
,即前一个时间间隔的值。
fill()
的常见问题
查询时间范围内没有数据的查询
目前,如果查询的时间范围内没有数据,则查询会忽略 fill()
。这是预期行为。GitHub 上的一个开放 功能请求 建议即使查询的时间范围不包含任何数据,fill()
也应强制返回值。
示例
以下查询不返回任何数据,因为 water_level
在查询的时间范围内没有数据点。请注意,fill(800)
对查询结果没有影响。
SELECT MEAN("water_level") FROM "h2o_feet" WHERE "location" = 'coyote_creek' AND time >= '2019-09-18T22:00:00Z' AND time <= '2019-09-18T22:18:00Z' GROUP BY time(12m) fill(800)
> no results
当先前结果超出查询时间范围时,使用 fill(previous)
的查询
如果先前的值超出查询的时间范围,则 fill(previous)
不会填充时间间隔的结果。
示例
以下示例查询 2019-09-18T16:24:00Z
和 2019-09-18T16:54:00Z
之间的时间范围。请注意,fill(previous)
使用 2019-09-18T16:24:00Z
的结果填充 2019-09-18T16:36:00Z
的结果。
SELECT MAX("water_level") FROM "h2o_feet" WHERE location = 'coyote_creek' AND time >= '2019-09-18T16:24:00Z' AND time <= '2019-09-18T16:54:00Z' GROUP BY time(12m) fill(previous)
输出
time | 最大值 |
---|---|
2019-09-18T16:24:00Z | 3.235 |
2019-09-18T16:36:00Z | 3.235 |
2019-09-18T16:48:00Z | 4 |
下一个示例查询 2019-09-18T16:36:00Z
和 2019-09-18T16:54:00Z
之间的时间范围。请注意,fill(previous)
不会使用 2019-09-18T16:24:00Z
的结果填充 2019-09-18T16:36:00Z
的结果;2019-09-18T16:24:00Z
的结果超出查询的较短时间范围。
SELECT MAX("water_level") FROM "h2o_feet" WHERE location = 'coyote_creek' AND time >= '2019-09-18T16:36:00Z' AND time <= '2019-09-18T16:54:00Z' GROUP BY time(12m) fill(previous)
输出
time | 最大值 |
---|---|
2019-09-18T16:36:00Z | |
2019-09-18T16:48:00Z | 4 |
当先前或后续结果超出查询时间范围时,使用 fill(linear)
如果先前结果或后续结果超出查询的时间范围,则 fill(linear)
不会填充没有数据的时间间隔的结果。
示例
以下示例查询 2019-11-11T21:24:00Z
和 2019-11-11T22:06:00Z
之间的时间范围。请注意,fill(linear)
使用 2019-11-11T21:24:00Z
时间间隔和 2019-11-11T22:00:00Z
时间间隔的值填充 2019-11-11T21:36:00Z
时间间隔和 2019-11-11T21:48:00Z
时间间隔的结果。
SELECT MEAN("tadpoles") FROM "pond" WHERE time > '2019-11-11T21:24:00Z' AND time <= '2019-11-11T22:06:00Z' GROUP BY time(12m) fill(linear)
输出
time | mean |
---|---|
2019-11-11T21:24:00Z | 3 |
2019-11-11T21:36:00Z | 4 |
2019-11-11T21:48:00Z | 5 |
2019-11-11T22:00:00Z | 6 |
下一个查询缩短了上一个查询中的时间范围。它现在涵盖了 2019-11-11T21:36:00Z
和 2019-11-11T22:06:00Z
之间的时间。请注意,fill()
previous 不会填充 2019-11-11T21:36:00Z
时间间隔和 2019-11-11T21:48:00Z
时间间隔的结果;2019-11-11T21:24:00Z
的结果超出查询的较短时间范围,并且 InfluxDB 无法执行线性插值。
SELECT MEAN("tadpoles") FROM "pond" WHERE time >= '2019-11-11T21:36:00Z' AND time <= '2019-11-11T22:06:00Z' GROUP BY time(12m) fill(linear)
输出
time | mean |
---|---|
2019-11-11T21:36:00Z | |
2019-11-11T21:48:00Z | |
2019-11-11T22:00:00Z | 6 |
注意: 问题 3 中的数据不在 NOAA
数据库中。我们必须创建一个数据不太规则的数据集才能使用 fill(linear)
。
此页面是否对您有帮助?
感谢您的反馈!
支持和反馈
感谢您成为我们社区的一份子!我们欢迎并鼓励您提供关于 InfluxDB 和本文档的反馈和错误报告。要获得支持,请使用以下资源
拥有年度合同或支持合同的客户可以联系 InfluxData 支持。