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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...