6.InfluxDB-InfluxQL基礎(chǔ)語法教程--GROUP BY子句

本文翻譯自官網(wǎng),官網(wǎng)地址:(https://docs.influxdata.com/influxdb/v1.7/query_language/data_exploration/)

GROUP BY子句通過用戶自己制定的tags set或time區(qū)間,來將查詢結(jié)果進(jìn)行分組。

GROUP BY tags

GROUP BY <tag> 通過用戶指定的tag set,來對查詢結(jié)果進(jìn)行分組。
語法

SELECT_clause FROM_clause [WHERE_clause]
GROUP BY [* | <tag_key>[,<tag_key]]
GROUP BY子句 意義
GROUP BY * 使用所有tag對查詢結(jié)果進(jìn)行分組
GROUP BY <tag_key> 使用指定tag對查詢結(jié)果進(jìn)行分組
GROUP BY <tag_key>,<tag_key> 使用指定的多個tag對查詢結(jié)果進(jìn)行分組,其中tag之間的順序是無關(guān)的。

:如果在sql中同時存在WHERE子句和GROUP BY子句,則GROUP BY子句一定要在WHERE子句之后!

Other supported features: Regular Expressions


GROUP BY tags 示例sql

  1. Group query results by a single tag

    上面的sql使用了MEAN函數(shù),來對h2o_feet這個measurement中的location這個tag進(jìn)行分組求平均值。
    注:在InfluxDB中,<font color=Red size=2>0紀(jì)元1970-01-01T00:00:00Z</font>這個時間經(jīng)常被用來表示timestamp的NULL值。如果你的查詢中沒有顯示指定返回一個timestamp,比如上面在調(diào)用聚合函數(shù)時,就沒有指定時間區(qū)間,因此InfluxDB最后返回0紀(jì)元來作為timestamp。
  1. Group query results by more than one tag
  1. Group query results by all tags

基礎(chǔ)GROUP BY time intervals

GROUP BY time() 查詢會將查詢結(jié)果按照用戶指定的時間區(qū)間來進(jìn)行分組。
語法:

SELECT <function>(<field_key>) FROM_clause
WHERE <time_range>
GROUP BY time(<time_interval>),[tag_key] [fill(<fill_option>)]

基本的 GROUP BY time() 查詢用法需要在SELECT子句中調(diào)用相關(guān)函數(shù),并且在WHERE子句中調(diào)用time時間區(qū)間。

  • time(time_interval)
    在GROUP BY time()子句中的time_interval是個連續(xù)的時間區(qū)間,該時間區(qū)間決定了InfluxDB如何通過時間來對查詢結(jié)果進(jìn)行分組。比如,如果time_interval為5m,那么它會將查詢結(jié)果分為5分鐘一組(如果在WHERE子句中指定了time區(qū)間,那么就是將WHERE中指定的time區(qū)間劃分為沒5分鐘一組)。

  • fill(<fill_option>)
    fill(<fill_option>) 是可選的。它可以填充那些沒有數(shù)據(jù)的時間區(qū)間的值。 從GROUP BY time intervals and fill() 部分可查看到關(guān)于這部分的更多信息。

    注:基本的GROUP BY time()查詢通過當(dāng)前InfluxDB數(shù)據(jù)庫的預(yù)設(shè)時間邊界來確定每個時間間隔中包含的原始數(shù)據(jù)和查詢返回的時間戳。


基本用法示例sql

先看一個WHERE查詢

下面的GROUP BY time(time_interval)示例是在上面的sql基礎(chǔ)上進(jìn)行改進(jìn)的,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)

查詢結(jié)果:


該sql將h2o_feet表中tag=“coyote_creek”,且在'2015-08-18T00:00:00Z'和'2015-08-18T00:30:00Z'時間區(qū)間內(nèi)的數(shù)據(jù)查詢出來,并對其劃分為每12分鐘一組,對water_level值進(jìn)行count計算。

注意:在查詢結(jié)果中,時間區(qū)間是左閉右開的。拿第一行查詢結(jié)果數(shù)據(jù)來說,2015-08-18T00:00:00Z表示的時間區(qū)間是[2015-08-18T00:00:00, 2015-08-18T00:12:00Z )


常見問題

問題:查詢結(jié)果中有預(yù)期之外的時間區(qū)間和值。
在基本用法中,GROUP BY time()查詢通過當(dāng)前InfluxDB數(shù)據(jù)庫的預(yù)設(shè)時間邊界來確定每個時間間隔中包含的原始數(shù)據(jù)和查詢返回的時間戳,這有可能會導(dǎo)致預(yù)期之外的結(jié)果值。
比如,通過如下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'

我們查詢到原始數(shù)據(jù)如下所示:

在接下來的查詢中,我們通過WHERE子句,指定查詢12分鐘內(nèi)的數(shù)據(jù),并通過GROUP BY子句,將查詢結(jié)果按12分鐘的時間區(qū)間進(jìn)行分組。

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)

按照預(yù)想,因為查詢的是12分鐘內(nèi)的數(shù)據(jù),并且group by時是按照12分鐘來進(jìn)行分組的,所以最后的查詢結(jié)果應(yīng)該只有一行而已。然后實際的查詢結(jié)果卻有兩行:


解釋
influxdb使用預(yù)設(shè)的整數(shù)時間邊界來作為GROUP BY的時間間隔,這些間隔獨立于WHERE子句中的任何時間條件。在計算結(jié)果時,所有返回的數(shù)據(jù)都必須出現(xiàn)在WHERE查詢的顯式時間范圍內(nèi),但當(dāng)按間隔作為GROUP BY分組時是基于預(yù)設(shè)的時間邊界。
(這里翻譯的不好,下面是原版英文:
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()語法允許用戶自定義預(yù)設(shè)時間邊界的開始時間。在高級語法小節(jié)的示例sql3中,將展示這種用法,它查詢的結(jié)果如下:



高級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子句中調(diào)用InfluxDB的函數(shù),并在WHERE子句中指定時間區(qū)間。并且需要注意到的是,GROUP BY子句必須在WHERE子句之后!

  • time(time_interval,offset_interval)
    在GROUP BY time()子句中的通過time_interval和offset_interval來表示一個連續(xù)的時間區(qū)間,該時間區(qū)間決定了InfluxDB如何通過時間來對查詢結(jié)果進(jìn)行分組。比如,如果時間區(qū)間為5m,那么它會將查詢結(jié)果分為5分鐘一組(如果在WHERE子句中指定了time區(qū)間,那么就是將WHERE中指定的time區(qū)間劃分為沒5分鐘一組)。
    offset_interval是持續(xù)時間文本。它向前或向后移動InfluxDB數(shù)據(jù)庫的預(yù)設(shè)時間邊界。offset_interval可以為正或負(fù)。

  • fill(<fill_option>)
    fill(<fill_option>)是可選的。 它可以填充那些沒有數(shù)據(jù)的時間區(qū)間的值。 從 GROUP BY time intervals and fill() 部分可查看到關(guān)于這部分的更多信息。

    :高級 GROUP BY time() 語法依賴于time_interval、offset_interval、以及 InfluxDB 數(shù)據(jù)庫的預(yù)設(shè)時間邊界來確定每組內(nèi)的數(shù)據(jù)條數(shù)、以及查詢結(jié)果的時間戳。


高級用法示例sql

先看如下查詢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'

查詢結(jié)果:


接下來將使用上面的樣例數(shù)據(jù)的子集來進(jìn)行演示。以下sql將按照每18m對數(shù)據(jù)進(jìn)行進(jìn)組,并將預(yù)設(shè)的時間界限前移。

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,6m)

查詢結(jié)果:


可見上面sql將查詢結(jié)果按照每18m為一組進(jìn)行了分組,并且將預(yù)設(shè)的時間界限偏移了6分鐘。
注意,對于沒有offset_interval的group by time(),它的查詢結(jié)果的時間邊界和返回的時間戳遵循influxdb數(shù)據(jù)庫的預(yù)設(shè)時間邊界。下面我們看offset_interval的group by time()的查詢結(jié)果:

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);

查詢結(jié)果


:該sql使用的是time(18m,-12m),offset_interval是負(fù)數(shù),它的查詢結(jié)果跟使用time(18m,6m)是一樣的。<font color=Red size=2>因此在決定正負(fù)偏移間隔時,請隨意選擇最直觀的選項。</font>


GROUP BY time intervals and fill()

Fill() 可以填充那些沒有數(shù)據(jù)的時間區(qū)間的值。
語法:

SELECT <function>(<field_key>) FROM_clause
WHERE <time_range>
GROUP BY time(time_interval,[<offset_interval])[,tag_key] [fill(<fill_option>)]

默認(rèn)情況下,在GROUP BY time()查詢結(jié)果中,若某個時間區(qū)間沒有數(shù)據(jù),則該時間區(qū)間對應(yīng)的值為null。通過fill(),就可以填充那些沒有數(shù)據(jù)的時間區(qū)間的值。
需要注意的是,fill()必須出現(xiàn)在GROUP BY子句的最后。

Fill選項

  1. 任何數(shù)學(xué)數(shù)值
    使用給定的數(shù)學(xué)數(shù)值進(jìn)行填充
  2. linear
    為沒有數(shù)據(jù)值的時間區(qū)間線性插入數(shù)值,使得插入之后的數(shù)值,跟其他本來就有數(shù)據(jù)的區(qū)間的值成線性。(這里翻譯的不是很好,看示例就能明白了)
  3. none
    若某個時間區(qū)間內(nèi)沒有數(shù)據(jù),則在查詢結(jié)果中該區(qū)間對應(yīng)的時間戳將不顯示出來
  4. null
    沒有值的區(qū)間,顯示為null。這也是默認(rèn)的選項。
  5. previous
    用前一個區(qū)間的數(shù)值來填充當(dāng)前沒有數(shù)據(jù)的區(qū)間的值。

示例:

1) fill(100)

2) fill(linear)

3) fill(none)

4) fill(null)

5) fill(previous)


至此,group by部分教程結(jié)束。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容