GROUP BY中的WITH CUBE、WITH ROLLUP、GROUPING測試

来源:https://www.cnblogs.com/atomy/archive/2019/11/05/11795921.html
-Advertisement-
Play Games

前幾天,看到一個群友用WITH ROLLUP,由於沒用過,閑來無事測試一下。 一、概念: WITH CUBE:生成的結果集顯示了所選列中值的所有組合的聚合。 WITH ROLLUP:生成的結果集顯示了所選列中值的某一層次結構的聚合。 GROUPING:當行由 WITH CUBE或WITH ROLLU ...


    前幾天,看到一個群友用WITH ROLLUP運算符。由於自個兒沒用過,看到概念及結果都雲里霧裡的,所以突然來了興趣對生成結果測了一番。

    一、概念:

    WITH CUBE:生成的結果集顯示了所選列中值的所有組合的聚合。

    WITH ROLLUP:生成的結果集顯示了所選列中值的某一層次結構的聚合。

    GROUPING:當行由 WITH CUBE或WITH ROLLUP運算符添加時,該函數將導致附加列的輸出值為 1;當行不由 CUBE 或 ROLLUP 運算符添加時,該函數將導致附加列的輸出值為 0。僅在與包含 CUBE 或 ROLLUP 運算符的 GROUP BY 子句相關聯的選擇列表中才允許分組。

    二、測試:

    1、建立臨時表

CREATE TABLE #T0
(
    [GRADE] [VARCHAR](50) NULL,     --年級
    [CLASS] [VARCHAR](50) NULL,     --班級
    [NAME] [VARCHAR](50) NULL,      --姓名
    [COURSE] [VARCHAR](50) NULL,    --學科
    [RESULT] [NUMERIC](8,2) NULL    --成績
)

CREATE TABLE #T1
(
    [ID] [INT] IDENTITY(1,1) NOT NULL,    --序號
    [GRADE] [VARCHAR](50) NULL,           --年級
    [CLASS] [VARCHAR](50) NULL,           --班級
    [NAME] [VARCHAR](50) NULL,            --姓名
    [COURSE] [VARCHAR](50) NULL,          --學科
    [RESULT] [NUMERIC](8,2) NULL          --成績
)

CREATE TABLE #T2
(
    [ID] [INT] IDENTITY(1,1) NOT NULL,    --序號
    [GRADE] [VARCHAR](50) NULL,           --年級
    [CLASS] [VARCHAR](50) NULL,           --班級
    [NAME] [VARCHAR](50) NULL,            --姓名
    [COURSE] [VARCHAR](50) NULL,          --學科
    [RESULT] [NUMERIC](8,2) NULL          --成績
)

     2、插入測試數據

INSERT INTO #T0 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT '2019','CLASS1','9A01','C#',100
UNION
SELECT '2019','CLASS1','9A02','C#',100
UNION
SELECT '2019','CLASS2','9B01','C#',100
UNION
SELECT '2019','CLASS2','9B02','C#',100
UNION
SELECT '2018','CLASS1','8A01','JAVA',100
UNION
SELECT '2018','CLASS1','8A02','JAVA',100
UNION
SELECT '2018','CLASS2','8B01','JAVA',100
UNION
SELECT '2018','CLASS2','8B02','JAVA',100

    查詢T0表結果:

    3、GROUP BY

    拋磚引玉,看看常用的GROUP BY排序:預設以SELECT欄位順序(GRADE->CLASS->NAME->COURSE)進行排序,以下兩種查詢結果是一樣的。

SELECT GRADE,CLASS,NAME,COURSE,SUM(RESULT) RESULT
FROM #T0
GROUP BY GRADE,CLASS,NAME,COURSE

SELECT GRADE,CLASS,NAME,COURSE,SUM(RESULT) RESULT
FROM #T0
GROUP BY GRADE,CLASS,NAME,COURSE
ORDER BY GRADE,CLASS,NAME,COURSE

    4、WITH CUBE

    原理1:以GROUP BY欄位依次賦以NULL值進行分組聚合。

    原理2:第1個欄位(即GRADE欄位)生成結果:除原始數據外,以第1個欄位固定賦以NULL值,然後其它欄位依次賦以NULL值進行分組聚合,結果由右往左進行排序

    下麵開始測第1個欄位的結果是怎麼來的:

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT GRADE,CLASS,NAME,COURSE,SUM(RESULT) RESULT 
FROM #T0 
GROUP BY GRADE,CLASS,NAME,COURSE

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT 'ZZ' GRADE,CLASS,NAME,COURSE,SUM(RESULT) RESULT 
FROM #T0 
GROUP BY CLASS,NAME,COURSE

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT 'ZZ' GRADE,'ZZ' CLASS,NAME,COURSE,SUM(RESULT) RESULT 
FROM #T0 
GROUP BY NAME,COURSE

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT 'ZZ' GRADE,'ZZ' CLASS,'ZZ' NAME,COURSE,SUM(RESULT) RESULT 
FROM #T0 
GROUP BY COURSE

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT 'ZZ' GRADE,'ZZ' CLASS,'ZZ' NAME,'ZZ' COURSE,SUM(RESULT) RESULT 
FROM #T0

--第1個欄位結果排序由右往左
INSERT INTO #T2 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT GRADE,CLASS,NAME,COURSE,RESULT FROM #T1 WHERE ID BETWEEN 1 AND 27 ORDER BY COURSE,NAME,CLASS,GRADE

UPDATE #T2 SET GRADE=NULL WHERE GRADE='ZZ'
UPDATE #T2 SET CLASS=NULL WHERE CLASS='ZZ'
UPDATE #T2 SET NAME=NULL WHERE NAME='ZZ'
UPDATE #T2 SET COURSE=NULL WHERE COURSE='ZZ'

    WITH CUBE的結果:

SELECT GRADE,CLASS,NAME,COURSE,SUM(RESULT) RESULT
FROM #T0
GROUP BY GRADE,CLASS,NAME,COURSE
WITH CUBE

    自已測試的結果:

SELECT * FROM #T2

    結果與上面一致。

    其它欄位優先跟哪個欄位組合、最終怎樣排序?呃,測過,沒搞清楚……

    5、WITH ROLLUP

    原理1:除原始數據外,以GROUP BY最後1個欄位(即COURSE欄位)固定賦以NULL值,然後其它欄位依次賦以NULL值進行分組聚合,結果由左往右進行排序

    這個跟WITH CUBE的第1個欄位非常相象:一個是第1個欄位,一個是最後1個欄位;一個結果是由右往左排序,一個結果是由左往右排序。

    下麵開始測結果是怎麼來的:

TRUNCATE TABLE #T1
TRUNCATE TABLE #T2

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT GRADE,CLASS,NAME,COURSE,SUM(RESULT) RESULT 
FROM #T0 
GROUP BY GRADE,CLASS,NAME,COURSE

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT GRADE,CLASS,NAME,'ZZ' COURSE,SUM(RESULT) RESULT 
FROM #T0 
WHERE NOT EXISTS (SELECT 1 FROM #T1 WHERE GRADE=#T0.GRADE AND CLASS=#T0.GRADE AND NAME=#T0.NAME AND COURSE='ZZ')
GROUP BY GRADE,CLASS,NAME

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT GRADE,CLASS,'ZZ' NAME,'ZZ' COURSE,SUM(RESULT) RESULT 
FROM #T0 
WHERE NOT EXISTS (SELECT 1 FROM #T1 WHERE GRADE=#T0.GRADE AND CLASS=#T0.CLASS AND NAME='ZZ' AND COURSE='ZZ')
GROUP BY GRADE,CLASS

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT GRADE,'ZZ' CLASS,'ZZ' NAME,'ZZ' COURSE,SUM(RESULT) RESULT 
FROM #T0 
WHERE NOT EXISTS (SELECT 1 FROM #T1 WHERE GRADE=#T0.GRADE AND CLASS='ZZ' AND NAME='ZZ' AND COURSE='ZZ')
GROUP BY GRADE

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT 'ZZ' GRADE,'ZZ' CLASS,'ZZ' NAME,'ZZ' COURSE,SUM(RESULT) RESULT 
FROM #T0 

--結果排序由左往右
INSERT INTO #T2 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT GRADE,CLASS,NAME,COURSE,RESULT FROM #T1 ORDER BY GRADE,CLASS,NAME,COURSE

UPDATE #T2 SET GRADE=NULL WHERE GRADE='ZZ'
UPDATE #T2 SET CLASS=NULL WHERE CLASS='ZZ'
UPDATE #T2 SET NAME=NULL WHERE NAME='ZZ'
UPDATE #T2 SET COURSE=NULL WHERE COURSE='ZZ'

    WITH ROLLUP的結果:

SELECT GRADE,CLASS,NAME,COURSE,SUM(RESULT) RESULT
FROM #T0
GROUP BY GRADE,CLASS,NAME,COURSE
WITH ROLLUP

    自己測試的結果:

SELECT * FROM #T2

    結果與上面一致。

    6、GROUPING

    這個就比較容易理解了,WITH CUBE與WITH ROLLUP用法一樣,先看結果:

SELECT GRADE,CLASS,NAME,COURSE,SUM(RESULT) RESULT,GROUPING(COURSE) [GROUPING]
FROM #T0
GROUP BY GRADE,CLASS,NAME,COURSE
WITH ROLLUP

    上面GROUPING的是COURSE欄位,有NULL值就是WITH ROLLUP額外添加的,GROUPING結果值為1。

    有了GROUPING,那做小計、總計就方便了。

SELECT 
    GRADE,
    CASE WHEN GROUPING(GRADE)=1 AND GROUPING(CLASS)=1 THEN '總計' WHEN GROUPING(GRADE)=0 AND GROUPING(CLASS)=1 THEN '小計' ELSE CLASS END CLASS,
    NAME,COURSE,SUM(RESULT) RESULT
FROM #T0
GROUP BY GRADE,CLASS,NAME,COURSE
WITH ROLLUP

     好了,原理測試及應用就到這裡結束了。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 之前搭建openvpn和easy2.0組合,第一次幫朋友搭建easy3.0組合感覺比2.0麻煩一些,參考了很多技術文章 搭建yum install -y install openvpn easy-rsa net-tools bridge-utilscd /usr/share/easy-rsa/3./ ...
  • 廢話不多說,直接進入主題。 1、安裝mailx [root@localhost ~]#yum install malix -y #yum安裝malix [root@localhost ~]# vi /etc/malix.rc #配置郵箱,配置第三方軟體發送郵件。 2、在配置文件的最後添加第三方郵件的 ...
  • 通常的Cortex-M內核MCU一般都會內嵌並行NOR Flash,這個並行NOR Flash是直接掛在Cortex-M內核高性能AHB匯流排上的,知名IDE如果支持這款MCU,也都會同時集成對應Flash的下載演算法,方便用戶直接在IDE里下載代碼進Flash和XIP調試,但是i.MXRT內部並沒有F... ...
  • 1.poweroff 功能描述:可以關閉Linux系統,關閉記錄會被寫入/var/log/wtmp日誌文件中 命令語法:poweroff [選項] 選項含義: -n:關閉之前不同步 -p:當被稱為halt時關閉電源 -v:增加輸出,包括消息 -q:降低輸出錯誤唯一的消息 -w:並不實際關閉系統,只是 ...
  • 1.電腦組成 2.開發介面標準 ABI--(Application Binary Interface) ABI描述了應用程式與OS之間的底層介面,允許編譯好的目標代碼在使用相容ABI的系統中無需改動就能運行。 API--(Application Programming Interface) API ...
  • 預設已安裝Prometheus服務,服務地址:192.168.56.200 一、獲取交換機snmp信息 snmp服務IP(交換機IP):172.20.2.83 snmp community:dfetest 二、部署 snmp_exporter 2.1 下載snmp_exporter 下載snmp_e ...
  • 磁碟: 設備類型: 塊設備:block,磁碟 字元設備:char,鍵盤 brw-rw . 1 root disk 8, 0 Nov 3 09:42 sda 主設備號 次設備號查看硬碟類型: cat /sys/block/sda/queue/rotational0 --表示固態硬碟1 --表示機械硬碟 ...
  • [20191101]通過zsh計算sql語句的sql_id.txt1.簡單介紹以及測試使用zsh遇到的問題:--//前段時間寫的,鏈接http://blog.itpub.net/267265/viewspace-2659623/=>[20191011]通過bash計算sql語句的sql_id.txt ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...