GROUP BY子句通常與彙總函式一起使用,用來對查詢結果中的資料行進行分組。每個分組都基於一列或多列的值。通過這種方式,可以為每個不同的組合產生一個合計列,從而協助使用者更有效地分析資料。此外,GROUP BY子句還可以搭配ROLLUP、CUBE和GROUPING SETS子句,以擴充其分組功能,提供更多樣化的資料分析選項。
基本文法
GROUP BY
對分析結果進行分組。
SELECT
key1,
...
aggregate_function
GROUP BY
key,...
參數說明如下所示:
-
key1:是您希望根據其值來分組的列,支援按照日誌欄位名稱或彙總函式計算結果列進行分組。GROUP BY子句支援單列或多列。 -
aggregate_function:是應用在每個分組上的彙總函式,如count、min、max、avg和sum等。
GROUP BY ROLLUP
GROUP BY ROLLUP子句按照匯總分組,支援為每個分組返回一個小計,為所有分組返回一個總計。例如GROUP BY ROLLUP (a, b)的結果集為(a, b)、(a, null)和 (null, null)。
SELECT
key1,
...
aggregate_function
GROUP BY ROLLUP (key1,...)
參數說明如下所示:
-
key1:是您希望根據其值來分組的列,支援按照日誌欄位名稱或彙總函式計算結果列進行分組。GROUP BY子句支援單列或多列。 -
aggregate_function:是應用在每個分組上的彙總函式,如count、min、max、avg和sum等。
GROUP BY CUBE
GROUP BY CUBE子句按照所有可能的列組合進行分組。例如GROUP BY CUBE (a, b)的結果集為(a, b)、(null, b)、(a, null) 和(null, null) 。
SELECT
key1,
...
aggregate_function
GROUP BY CUBE (key1,...)
參數說明如下所示:
-
key1:是您希望根據其值來分組的列,支援按照日誌欄位名稱或彙總函式計算結果列進行分組。GROUP BY子句支援單列或多列。 -
aggregate_function:是應用在每個分組上的彙總函式,如count、min、max、avg和sum等。
GROUP BY GROUPING SETS
GROUP BY GROUPING SETS子句按照列依次進行分組。例如GROUP BY GROUPING SETS (a, b)的結果集為(a, null)和(null, b)。
SELECT
key1,
...
aggregate_function
GROUP BY GROUPING SETS (key1,...)
參數說明如下所示:
-
key1:是您希望根據其值來分組的列,支援按照日誌欄位名稱或彙總函式計算結果列進行分組。GROUP BY子句支援單列或多列。 -
aggregate_function:是應用在每個分組上的彙總函式,如count、min、max、avg和sum等。
樣本
在SQL語句中,如果使用了GROUP BY子句,則在SELECT語句中只能選擇以下兩類內容:
-
GROUP BY子句中指定的列; -
對任意列進行彙總計算的結果(如
COUNT()、SUM()等)。
直接選擇非GROUP BY列是不允許的,因為這些列的值在分組後可能不唯一,無法明確其含義。例如,以下語句是非法的:
* | SELECT status, request_time, COUNT(*) AS PV GROUP BY status
原因是request_time並未包含在GROUP BY子句中,且未對其進行彙總處理。
正確的寫法可以是:
* | SELECT status, arbitrary(request_time), COUNT(*) AS PV GROUP BY status
在這裡,arbitrary(request_time)是對request_time進行彙總處理的一種方式,表示從每個分組中任意選取一個request_time值。這樣既符合 SQL 的文法規則,又能滿足查詢需求。
-
樣本1
統計不同狀態代碼對應的請求次數。
-
查詢和分析語句
* | SELECT status, count(*) AS PV GROUP BY status -
查詢和分析結果以表格形式展示,包含 status 和 PV 兩列,分別顯示各 HTTP 狀態代碼及其對應的頁面訪問量統計值。
-
-
樣本2
按照每小時的時間粒紋計算網站訪問PV。
-
查詢和分析語句
__time__欄位為Log Service中的保留欄位,表示時間列。time為date_trunc('hour', __time__)的別名。關於date_trunc函數的更多資訊,請參見date_trunc函數。* | SELECT count(*) AS PV, date_trunc('hour', __time__) AS time GROUP BY time ORDER BY time LIMIT 1000 -
查詢和分析結果:查詢返回包含 PV 和 time 兩列的結果,樣本資料:PV 分別為 1202、10159、28001,對應時間為 2021-08-10 00:00:00.000、2021-08-10 01:00:00.000、2021-08-10 02:00:00.000。
-
-
樣本3
按照每5分鐘的時間粒紋計算PV。
-
查詢和分析語句
因為
date_trunc函數只能按照固定時間間隔統計。如果您需要按照自訂的時間進行統計分析,請按照數學模數方法進行分組。例如%300表示按照5分鐘的時間粒紋進行模數對齊。* | SELECT count(*) AS PV, __time__-__time__ % 300 AS time GROUP BY time LIMIT 1000 -
查詢和分析結果返回三條記錄:PV=143 對應 time=1628525100,PV=31 對應 time=1628526600,PV=44 對應 time=1628526900。
-
-
樣本4
根據要求方法和請求狀態分組,先計算各個要求方法對應的訪問資料,再計算各個請求狀態對應的訪問數量。
-
查詢和分析語句
* | SELECT request_method, status, count(*) AS PV GROUP BY GROUPING SETS (request_method, status) -
查詢和分析結果:按
request_method分組時,status為 null,各方法 PV 值分別為:GET=285、POST=51、DELETE=28、PUT=60;按status分組時,request_method為 null,各狀態代碼 PV 值分別為:200=382、204=2、501=2、202=4、305=4。
-
-
樣本5
根據要求方法和請求狀態分組,分組集包括
(null, null)、(request_method, null)、(null, status)和(request_method, status),計算以上各個分組的訪問數量。-
查詢和分析語句
* | SELECT request_method, status, count(*) AS PV GROUP BY CUBE (request_method, status) -
查詢和分析結果:查詢結果包含 request_method、status、PV 三列,共 43 條記錄。CUBE 分組產生的彙總行中,
request_method或status為 null 表示該維度小計。例如:null/null 的 PV 為 285(總計),GET/null 為 189,POST/null 為 47,PUT/null 為 39,DELETE/null 為 9,HEAD/null 為 1;null/200 為 259,null/201 為 2,null/202 為 2。
-
-
樣本6
根據要求方法和請求狀態分組,分組集包括
(request_method, status)、(request_method, null)和(null, null),計算以上各個分組的訪問數量。-
查詢和分析語句
* | SELECT request_method, status, count(*) AS PV GROUP BY ROLLUP (request_method, status) -
查詢和分析結果:查詢結果包含 request_method、status、PV 三列,共 33 條記錄。ROLLUP 函數在各分組層級產生合計列,其中
null表示該列已被彙總:例如GET / null / 162表示 GET 方法所有狀態代碼的合計 PV 為 162,null / null / 285表示所有方法與狀態代碼的總計 PV 為 285。
-