本文翻译自官网,官网地址:(https://docs.influxdata.com/influxdb/v1.7/query_language/data_exploration/)sql
GROUP BY子句经过用户本身制定的tags set或time区间,来将查询结果进行分组。数据库
GROUP BY <tag> 经过用户指定的tag set,来对查询结果进行分组。
语法:express
SELECT_clause FROM_clause [WHERE_clause] GROUP BY [* | <tag_key>[,<tag_key]]
GROUP BY子句 | 意义 |
---|---|
GROUP BY * | 使用全部tag对查询结果进行分组 |
GROUP BY <tag_key> | 使用指定tag对查询结果进行分组 |
GROUP BY <tag_key>,<tag_key> | 使用指定的多个tag对查询结果进行分组,其中tag之间的顺序是无关的。 |
注 :若是在sql中同时存在WHERE子句和GROUP BY子句,则GROUP BY子句必定要在WHERE子句以后!函数
Other supported features: Regular Expressionsspa
Group query results by a single tag
上面的sql使用了MEAN函数,来对h2o_feet这个measurement中的location这个tag进行分组求平均值。
注:在InfluxDB中,<font color=Red size=2>0纪元1970-01-01T00:00:00Z</font>这个时间常常被用来表示timestamp的NULL值。若是你的查询中没有显示指定返回一个timestamp,好比上面在调用聚合函数时,就没有指定时间区间,所以InfluxDB最后返回0纪元来做为timestamp。翻译
Group query results by more than one tag
3d
Group query results by all tags
code
GROUP BY time() 查询会将查询结果按照用户指定的时间区间来进行分组。
语法:blog
SELECT <function>(<field_key>) FROM_clause WHERE <time_range> GROUP BY time(<time_interval>),[tag_key] [fill(<fill_option>)]
基本的 GROUP BY time() 查询用法须要在SELECT子句中调用相关函数,而且在WHERE子句中调用time时间区间。flux
time(time_interval)
在GROUP BY time()子句中的time_interval是个连续的时间区间,该时间区间决定了InfluxDB如何经过时间来对查询结果进行分组。好比,若是time_interval为5m,那么它会将查询结果分为5分钟一组(若是在WHERE子句中指定了time区间,那么就是将WHERE中指定的time区间划分为没5分钟一组)。
fill(<fill_option>)
fill(<fill_option>) 是可选的。它能够填充那些没有数据的时间区间的值。 从 [GROUP BY time intervals and fill() ] (https://docs.influxdata.com/influxdb/v1.7/query_language/data_exploration/#group-by-time-intervals-and-fill) 部分可查看到关于这部分的更多信息。
注:基本的GROUP BY time()查询经过当前InfluxDB数据库的预设时间边界来肯定每一个时间间隔中包含的原始数据和查询返回的时间戳。
先看一个WHERE查询
下面的GROUP BY time(time_interval)示例是在上面的sql基础上进行改进的,sql为:
SELECT COUNT("water_level") FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2015-08-18T00:00:00Z' AND time <= '2015-08-18T00:30:00Z' GROUP BY time(12m)
查询结果:
该sql将h2o_feet表中tag=“coyote_creek”,且在'2015-08-18T00:00:00Z'和'2015-08-18T00:30:00Z'时间区间内的数据查询出来,并对其划分为每12分钟一组,对water_level值进行count计算。
注意:在查询结果中,时间区间是左闭右开的。拿第一行查询结果数据来讲,2015-08-18T00:00:00Z表示的时间区间是[2015-08-18T00:00:00, 2015-08-18T00:12:00Z )
问题:查询结果中有预期以外的时间区间和值。
在基本用法中,GROUP BY time()查询经过当前InfluxDB数据库的预设时间边界来肯定每一个时间间隔中包含的原始数据和查询返回的时间戳,这有可能会致使预期以外的结果值。
好比,经过以下sql:
SELECT "water_level" FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2015-08-18T00:00:00Z' AND time <= '2015-08-18T00:18:00Z'
咱们查询到原始数据以下所示:
在接下来的查询中,咱们经过WHERE子句,指定查询12分钟内的数据,并经过GROUP BY子句,将查询结果按12分钟的时间区间进行分组。
SELECT COUNT("water_level") FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2015-08-18T00:06:00Z' AND time < '2015-08-18T00:18:00Z' GROUP BY time(12m)
按照预想,由于查询的是12分钟内的数据,而且group by时是按照12分钟来进行分组的,因此最后的查询结果应该只有一行而已。而后实际的查询结果却有两行:
解释 : influxdb使用预设的整数时间边界来做为GROUP BY的时间间隔,这些间隔独立于WHERE子句中的任什么时候间条件。在计算结果时,全部返回的数据都必须出如今WHERE查询的显式时间范围内,但当按间隔做为GROUP BY分组时是基于预设的时间边界。
(这里翻译的很差,下面是原版英文:
InfluxDB uses preset round-number time boundaries for GROUP BY intervals that are independent of any time conditions in the WHERE clause. When it calculates the results, all returned data must occur within the query’s explicit time range but the GROUP BY intervals will be based on the preset time boundaries. )
高级的GROUP BY time()语法容许用户自定义预设时间边界的开始时间。在高级语法小节的示例sql3中,将展现这种用法,它查询的结果以下:
语法以下:
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子句中调用InfluxDB的函数,并在WHERE子句中指定时间区间。而且须要注意到的是,GROUP BY子句必须在WHERE子句以后!
time(time_interval,offset_interval)
在GROUP BY time()子句中的经过time_interval和offset_interval来表示一个连续的时间区间,该时间区间决定了InfluxDB如何经过时间来对查询结果进行分组。好比,若是时间区间为5m,那么它会将查询结果分为5分钟一组(若是在WHERE子句中指定了time区间,那么就是将WHERE中指定的time区间划分为没5分钟一组)。
offset_interval是持续时间文本。它向前或向后移动InfluxDB数据库的预设时间边界。offset_interval能够为正或负。
fill(<fill_option>)
fill(<fill_option>)是可选的。 它能够填充那些没有数据的时间区间的值。 从 GROUP BY time intervals and fill() 部分可查看到关于这部分的更多信息。
注:高级 GROUP BY time() 语法依赖于time_interval、offset_interval、以及 InfluxDB 数据库的预设时间边界来肯定每组内的数据条数、以及查询结果的时间戳。
先看以下查询sql
SELECT "water_level" FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2015-08-18T00:00:00Z' AND time <= '2015-08-18T00:54:00Z'
查询结果:
接下来将使用上面的样例数据的子集来进行演示。如下sql将按照每18m对数据进行进组,并将预设的时间界限前移。
ELECT MEAN("water_level") FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2015-08-18T00:06:00Z' AND time <= '2015-08-18T00:54:00Z' GROUP BY time(18m,6m)
查询结果:
可见上面sql将查询结果按照每18m为一组进行了分组,而且将预设的时间界限偏移了6分钟。
注意,对于没有offset_interval的group by time(),它的查询结果的时间边界和返回的时间戳遵循influxdb数据库的预设时间边界。下面咱们看offset_interval的group by time()的查询结果:
SELECT MEAN("water_level") FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2015-08-18T00:06:00Z' AND time <= '2015-08-18T00:54:00Z' GROUP BY time(18m)
再看以下sql:
SELECT MEAN("water_level") FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2015-08-18T00:06:00Z' AND time <= '2015-08-18T00:54:00Z' GROUP BY time(18m,-12m);
查询结果
注 :该sql使用的是time(18m,-12m),offset_interval是负数,它的查询结果跟使用time(18m,6m)是同样的。<font color=Red size=2>所以在决定正负偏移间隔时,请随意选择最直观的选项。</font>
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(),就能够填充那些没有数据的时间区间的值。
须要注意的是,fill()必须出如今GROUP BY子句的最后。
Fill选项
fill(100)
fill(linear)
fill(none)
fill(null)
fill(previous)