全部產品
Search
文件中心

Simple Log Service:GROUP BY子句

更新時間:Sep 25, 2026

GROUP BY 子句通常與彙總函式一起使用,按照一列或多列的值對查詢結果中的資料行分組,為每個不同的組合產生一個合計列。除顯式指定分組鍵外,還可以使用 GROUP BY ALL 根據 SELECT 列表自動確定分組鍵,或搭配 ROLLUP、CUBE 和 GROUPING SETS 子句擴充分組功能。

基本文法

可根據分析情境選擇以下分組寫法,其中 ROLLUP、CUBE、GROUPING SETS 在 GROUP BY 基礎上擴充分組功能:

分析情境

適用寫法

按顯式指定的列或運算式對分析結果分組(最常用)

GROUP BY

分組鍵較多或需要調整分析維度,由 SELECT 列表自動確定分組鍵

GROUP BY ALL

為每個分組返回一個小計,為所有分組返回一個總計

GROUP BY ROLLUP

按照所有可能的列組合分組

GROUP BY CUBE

按照指定的多個分組集合分別分組

GROUP BY GROUPING SETS

重要

在 SQL 陳述式中,普通分組查詢的 SELECT 列表只能包含以下內容:

  • GROUP BY 子句中指定的列或運算式

  • 對任意列的彙總計算結果,如 COUNT()、SUM() 等

  • 使用 GROUP BY ALL 時,分組鍵由 SELECT 列表自動推導,無需在 GROUP BY 子句中重複列出。

  • 還可以在分組結果上使用視窗函數,參見樣本 9。

直接選擇非 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 文法規則,又能滿足查詢需求。

GROUP BY

對分析結果分組。

SELECT
 key1,
 ...,
 aggregate_function
GROUP BY key,...

參數說明:

  • key1:分組鍵,即用於分組的列,支援按日誌欄位名稱或彙總函式計算結果列分組。GROUP BY 子句支援單列或多列。

  • aggregate_function:應用在每個分組上的彙總函式,如 count、min、max、avg 和 sum 等。

完整樣本參見樣本 1~樣本 3。

GROUP BY ALL

GROUP BY ALL 自動將 SELECT 列表中不包含彙總函式、也不包含視窗函數的運算式作為分組鍵,無需在 GROUP BY 子句中重複列出這些運算式。適合分組鍵較多,或需要調整分析維度情境。

SELECT
 key1,
 key2,
 aggregate_function
GROUP BY ALL

參數說明:

  • key1、key2:分組鍵,可以是欄位或運算式,例如 status、request_method、substr(request_method, 1, 1) 或 CASE 運算式。運算式按其完整計算結果分組;GROUP BY ALL 後不跟任何欄位或別名,SELECT 列表中已設定的別名無需重複引用。

  • aggregate_function:應用在每個分組上的彙總函式,例如 count(*)、sum(request_time) 和 avg(request_time)。

例如,以下兩條語句等價:

* | SELECT request_method, status, count(*) AS PV GROUP BY ALL
* | SELECT request_method, status, count(*) AS PV GROUP BY request_method, status

SELECT 列表的通用合法性規則參見本章開頭的重要提示,GROUP BY ALL 的使用規則和限制如下:

  • 自動分組以當前 SELECT 列表為準,不會按日誌中的全部欄位分組。增加或刪除非彙總、非視窗運算式會相應改變分組維度。

  • 不支援在同一層查詢中將 GROUP BY ALL 與 SELECT *、SELECT 表別名.* 或 SELECT *, count(*) 組合使用,請顯式列出欄位。該限制針對 SELECT * 這類通配選擇,顯式列出欄位後使用 count(*) 等彙總函式不受影響。

  • 包含彙總函式或視窗函數的整個運算式不會被自動加入分組鍵,例如 sum(request_time) / count(*) 整體不參與分組。如果此類運算式之外還直接選擇了未彙總的欄位(例如未經 arbitrary() 等彙總函式處理的 request_time),仍須滿足普通 GROUP BY 的分組規則。

  • 當 SELECT 列表只有彙總運算式時,對全部符合查詢條件的資料全域彙總。例如 * | SELECT count(*) AS PV, sum(request_time) AS total_time GROUP BY ALL 與省略 GROUP BY ALL 的寫法等價。

  • 支援與 WHERE、HAVING、ORDER BY 以及視窗函數配合使用。視窗函數基於分組彙總後的結果計算,其引用的欄位仍需滿足分組規則。

  • 只有單獨書寫的 GROUP BY ALL 才會自動推導分組鍵,GROUP BY ALL status 或 GROUP BY ALL ROLLUP (...) 中的 ALL 不會觸發自動推導。

  • 需要按名為 all 的欄位或別名分組時,請使用雙引號,例如 GROUP BY "all"。預設情況下,即使存在名為 all 的欄位,單獨的 GROUP BY ALL 仍會自動推導分組鍵。

完整樣本參見樣本 7~樣本 9。

GROUP BY ROLLUP

GROUP BY ROLLUP 子句按匯總層級分組,為每個分組返回一個小計,為所有分組返回一個總計。例如 GROUP BY ROLLUP (a, b) 的結果集為 (a, b)、(a, null) 和 (null, null)。完整樣本參見樣本 6。

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)。完整樣本參見樣本 5。

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 子句按照指定的多個分組集合分別分組,未參與某個分組集合的列在該集合的結果中為 null。例如 GROUP BY GROUPING SETS (a, b) 的結果集為 (a, null) 和 (null, b)。完整樣本參見樣本 4。

SELECT
 key1,
 ...,
 aggregate_function
GROUP BY GROUPING SETS (key1,...)

參數說明如下所示:

  • key1:是您希望根據其值來分組的列,支援按照日誌欄位名稱或彙總函式計算結果列進行分組。GROUP BY子句支援單列或多列。

  • aggregate_function:是應用在每個分組上的彙總函式,如count、min、max、avg和sum等。

樣本

樣本 1:按狀態代碼統計請求次數

統計不同狀態代碼對應的請求次數。

  • 查詢和分析語句

* | SELECT status, count(*) AS PV GROUP BY status
  • 查詢和分析結果以表格形式展示,包含 status 和 PV 兩列,分別顯示各 HTTP 狀態代碼及其對應的頁面訪問量統計值。

樣本 2:按小時統計網站訪問 PV

按照每小時的時間粒紋計算網站訪問 PV。

  • 查詢和分析語句

    __time__ 欄位為Log Service中的保留欄位,表示時間列;time 為 date_trunc('hour', __time__) 的別名,函數用法參見 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

按照每 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:按指定分組集合統計訪問資料 (GROUPING SETS)

根據要求方法和請求狀態分組,先計算各個要求方法對應的訪問資料,再計算各個請求狀態對應的訪問數量。

  • 查詢和分析語句

* |
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:按所有列組合統計訪問資料 (CUBE)

根據要求方法和請求狀態分組,分組集包括 (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:按匯總層級統計小計與總計 (ROLLUP)

根據要求方法和請求狀態分組,分組集包括 (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。

樣本 7:自動按多個欄位分組 (GROUP BY ALL)

根據要求方法和狀態代碼統計請求次數,只保留請求次數大於 100 的分組。

  • 查詢和分析語句

* |
SELECT
 request_method,
 status,
 count(*) AS PV
GROUP BY ALL
HAVING count(*) > 100
ORDER BY PV DESC
  • 查詢和分析結果:包含 request_method、status 和 PV 三列,僅返回請求次數大於 100 的組合,並按 PV 從高到低排列。分組方式等價於 GROUP BY request_method, status。

樣本 8:自動按運算式分組 (GROUP BY ALL)

按照每 5 分鐘的時間粒紋和要求方法統計 PV,無需重複填寫時間運算式或其別名。

  • 查詢和分析語句

* |
SELECT
 __time__ - __time__ % 300 AS time,
 request_method,
 count(*) AS PV
GROUP BY ALL
ORDER BY time, request_method
LIMIT 1000
  • 查詢和分析結果:包含 time、request_method 和 PV 三列。分組方式等價於 GROUP BY __time__ - __time__ % 300, request_method。

樣本 9:對分組結果計算排名 (GROUP BY ALL)

統計各狀態代碼的請求次數,再按照請求次數從高到低計算排名。

  • 查詢和分析語句

* |
SELECT
 status,
 count(*) AS PV,
 rank() OVER (ORDER BY count(*) DESC) AS ranking
GROUP BY ALL
ORDER BY ranking, status
  • 查詢和分析結果:包含 status、PV 和 ranking 三列。僅 status 作為分組鍵,count(*) 用於彙總,rank() 對彙總結果排名,不參與分組;請求次數相同的狀態代碼具有相同排名。