偶然在網上看到一篇文章,講到數據匯總,提到了CUBE,感覺有些晦澀,想試着自己表述一下。同時,個人也認為CUBE還是很有用的,對SQL或數據分析感興趣的小伙伴不妨了解一下,或許有用呢!
先設定個需求,想要分別按【性別】、【籍貫】、【年齡】或【成績級別】統計下表中學生的數量,再進一步,需要將這些條件相結合統計,同時滿足某兩項或更多條件的學生數量。數據表格如下:
我們可以逐層來理解【GROUP BY】【WITH ROLLUP】【WITH CUBE】如何來完成數據匯總
第一層:【GROUP BY】
【GROUP BY】從字面意義上理解就是根據【BY】指定的規則對數據進行分組,所謂的分組就是將一個“數據集”划分成若干個“小區域”,然后針對若干個“小區域”進行數據處理。可以先利用【GROUP BY】按條件進行分組,然后計算各組的數量。看個例子。
按學生性別統計學生的數量:
SQL語句如下:
1 SELECT 性別, COUNT(學號) AS 數量 2 FROM STUDENT 3 GROUP BY 性別
執行結果如下:
結果分析:可以看出,已經按性別順利統計出“男”、“女”各占的數量,但這距離事先的需求(要統計多個條件,甚至是多條件組合下的學生數量的小計以及合計)差距有點遠,【GROUP BY】還是有點弱。
第二層:【GROUP BY】+【WITH ROLLUP】
為【GROUP BY】加上【WITH ROLLUP】子句,看ROLLUP能不能提供更多的統計結果。前面說到多條件,其實說多維度更准確些。看個例子先:
SQL語句如下:
1 --語句只用了【性別】一個維度進行匯總 2 SELECT 性別, COUNT(學號) AS 數量 3 FROM STUDENT 4 GROUP BY 性別 WITH ROLLUP 5 6 --語句用了【性別】和【籍貫】兩個維度進行匯總 7 SELECT 性別, 籍貫, COUNT(學號) AS 數量 8 FROM STUDENT 9 GROUP BY 性別, 籍貫 WITH ROLLUP 10 11 --語句用了【性別】、【籍貫】、【年齡】三個維度進行匯總 12 SELECT 性別, 籍貫, 年齡, COUNT(學號) AS 數量 13 FROM STUDENT 14 GROUP BY 性別, 籍貫, 年齡 WITH ROLLUP
執行結果如下:
結果分析:可以看出,ROLLUP提供了更多的統計數據,並且在結果中包含了很多“NULL”值的數據行,其實這些含“NULL”的數據行就是ROLLUP提供的匯總項,再仔細分析一下,不難看出,ROLLUP計算了指定分組(就是匯總的維度)的多個層次的數量小計以及合計,先逐步創建高一級別的小計,最后再創建一行總計。整體結果都是以【性別】這一層次進行數據聚合(這也是與CUBE的不同之處)。
第三層:【GROUP BY】+【WITH CUBE】
還有沒有更多組合的數據聚合,CUBE可以提供所選擇列的所有組合的聚合。簡單說,CUBE生成的結果是個多維數據集,就是包含各個維度的所有可能組合的交叉表格。看個例子先:
SQL語句如下:
1 --語句只用了【性別】和【籍貫】兩個維度進行匯總 2 SELECT 性別, 籍貫, COUNT(學號) AS 數量 3 FROM STUDENT 4 GROUP BY 性別, 籍貫 WITH CUBE
執行結果如下:
結果分析:與上面的ROLLUP的結果進行對比,是不是可以看到更多的結果數據。不僅有性別的小計,還有籍貫的小計。CUBE可以為指定的列創建各種不同組合的小計,是一種比 ROLLUP更細粒度的分組統計語句。如果將統計維度調整到三個維度,會與ROLLUP有更大的差異,三個維度下的CUBE結果有點多,篇幅有限,就用個GIF展示下,感興趣的小伙伴可以自己試一下。
最后,引用一下書面的總結,CUBE和ROLLUP之間的區別在於:
CUBE 生成的結果集顯示了所選列中值的所有組合的聚合。
ROLLUP 生成的結果集顯示了所選列中值的某一層次結構的聚合。
感覺也可以這樣來說:ROLLUP就是將GROUP BY后面的第一列名稱求總和,而其他列並不要求,而CUBE則會將每一個列名稱都求總和。
OK!就醬紫,水平有限,希望能給看到朋友一點小小的幫助。
也可關注一下微信公眾號,共同學習交流。