介紹一種非常好用彙總數據的方式GROUPING SETS

来源:https://www.cnblogs.com/wenBlog/archive/2018/02/11/8440200.html
-Advertisement-
Play Games

介紹 對於任何人而言,用T-SQL語句來寫聚會查詢都是工作中重要的一環。我們大家也都很熟悉GROUP BY子句來實現聚合表達式,但是如果打算在一個結果集中包含多種不同的彙總結果,可能會比較麻煩。我將舉例展示給大家使用GROUPING SETS操作符來完成這個“混合的結果集”。 或許當我們在打算分析較 ...


介紹

  對於任何人而言,用T-SQL語句來寫聚會查詢都是工作中重要的一環。我們大家也都很熟悉GROUP BY子句來實現聚合表達式,但是如果打算在一個結果集中包含多種不同的彙總結果,可能會比較麻煩。我將舉例展示給大家使用GROUPING SETS操作符來完成這個“混合的結果集”。

  或許當我們在打算分析較大規模的數據集時,不知道從何下手,此時處理這種情況最好的方式就是彙總數據,快速的得到一個數據預覽。

在T-SQL中,使用GROUP BY子句在一個聚合查詢中來彙總需要的數據。這個子句由一組表達式定義的分組構成。結果集中每一行返回GROUP BY 子句中表達式的唯一值或者組合,並且聚合函數,像COUNT或者SUM等可以對查詢中的任何行進行聚合。但是,如果你想要多種不同組合的聚合時,一般有兩種方式:

  1.將不懂組合聚合的結果集UNIONALL在一起。

  2.使用 GROUPING SETS操作符,結合GROUP BY一起在一個語句中實現。

 

本文中,我會展示如何使用GROUPING SETS來實現這一目的。

準備數據集

本文中所有的查詢都使用AdventureWorks2012 資料庫中的數據,這裡提供一個下載地址方便使用(AdventureWorks2012

實例: Data Analyst at Adventure Works

 

比如你是一個數據分析師,對於公司今年的收入很感興趣。這意味著你需要分組彙總公司的每一年的收入,查詢語句如下:

Query 1. 彙總每年收入

 

 
USE AdventureWorks2012;
GO
 
SELECT
YEAR(OrderDate) AS OrderYear,
SUM(SubTotal) AS Income
FROM Sales.SalesOrderHeader
GROUP BY YEAR(OrderDate)
ORDER BY OrderYear;
GO

 

 

 

Query 1 返回結果集:

OrderYear

Income

2005

11331809

2006

30674773.2

2007

42011037.2

2008

25828762.1

 

 

根據這個結果集,可知該公2005到2008年的收入情況。這類數據信息對於商業分析來說很常見。

但是,如果你想要更多關於收入的信息,比如其他彙總條件,你必須要重新運行一個GROUP BY子句。比如查詢返回公司每個月的收入情況。查詢語句如下:

Query 2. 公司每個月的收入

 

SELECT
YEAR(OrderDate) AS OrderYear,
MONTH(OrderDate) AS OrderMonth,
SUM(SubTotal) AS Income
FROM Sales.SalesOrderHeader
GROUP BY YEAR(OrderDate), MONTH(OrderDate)
ORDER BY OrderYear, OrderMonth;
GO

 

 

結果集如下:

OrderYear

OrderMonth

Income

2005

7

962716.742

2005

8

2044600

2005

9

1639840.11

2005

10

1358050.47

2005

11

2868129.2

2005

12

2458472.43

2006

1

1309863.25

2006

2

2451605.62

2006

3

2099415.62

2006

4

1546592.23

2006

5

2942672.91

2006

6

1678567.42

2006

7

2894054.68

2006

8

4147192.18

2006

9

3235826.19

2006

10

2217544.45

2006

11

3388911.41

2006

12

2762527.22

2007

1

1756407.01

2007

2

2873936.93

2007

3

2049529.87

2007

4

2371677.7

2007

5

3443525.25

2007

6

2542671.93

2007

7

3554092.32

2007

8

5068341.51

2007

9

5059473.22

2007

10

3364506.26

2007

11

4683867.05

2007

12

5243008.13

2008

1

3009197.42

2008

2

4167855.43

2008

3

4221323.43

2008

4

3820583.49

2008

5

5194121.52

2008

6

5364840.18

2008

7

50840.63

 

 

這個結果集要比之前的更詳細一點。可以得到具體某個月的收入彙總。顯然GROUP BY 後面的列越多其越詳細,結果一般也越多(除非有傳遞依賴鍵)。

如果你仔細觀察兩個查詢,你會發現他們都是根據個子的分組表達式進行分組彙總的。前面的是按照年,後面的是按照年和月。

假如我想查看兩種彙總結果在一個結果集中應該怎麼處理那?為了實現這個目標,我們前面說了兩個方案,方案1就是使用UNION ALL,代碼如下: 

 

Query 3. 公司收入(每年|每月)

 

 
SELECT
YEAR(OrderDate) AS OrderYear,
NULL AS OrderMonth, --Dummy Column
SUM(SubTotal) AS Incomes
FROM Sales.SalesOrderHeader
GROUP BY YEAR(OrderDate)
UNION ALL
SELECT
YEAR(OrderDate) AS OrderYear,
MONTH(OrderDate) AS OrderMonth,
SUM(SubTotal) AS Incomes
FROM Sales.SalesOrderHeader
GROUP BY YEAR(OrderDate), MONTH(OrderDate)
ORDER BY OrderYear, OrderMonth;
GO

 

 

結果集如下圖所示:

  

其中紅色框內為按照年的彙總數據。藍色框內為按照年和月的分組彙總。

如圖所示兩個結果集被合併在一起了。註意。此時NULL出現在裡面,使用NULL作為假列來標識order year分組的結果。因為按年分組沒有這個列。

儘管你已經獲得了想要的結果,但是這樣需要完成兩次的語句,接下來我們嘗試一下grouping set,方案2。因為我們都是懶人嗎,所以這個方式一定要更加簡單。目的就是“更少代碼,相同結果”。接下來我們詳細看一下:

Query 4.使用 GROUPING SETS實現相同結果 

 

 
SELECT
YEAR(OrderDate) AS OrderYear,
MONTH(OrderDate) AS OrderMonth,
SUM(SubTotal) AS Incomes
FROM Sales.SalesOrderHeader
GROUP BY
GROUPING SETS
(
YEAR(OrderDate), --1st grouping set
(YEAR(OrderDate),MONTH(OrderDate)) --2nd grouping set
);
GO

 

結果集跟之前的一模一樣。但是新的代碼要少很多。GROUPING SETS 操作符要和GROUP  BY 子句在一起使用。並且允許我們可以做一個多分組的查詢。儘管如此,我們要仔細檢查指定的分組集。例如假如一個分組包含兩個列,假設列A和B,兩個列都需要包含在括弧內:(column A, column B)。如果沒有括弧,這個子句將會被定義為獨立的分組,結果就不同了。

上面語句的結果如下:

http://www.sqlservercentral.com/Images/33650.jpg

 

 

順便說一下,如果我們打算聚合整個結果集(不分組聚合所有數據),只需要添加有一個空的括弧在分組集裡面即可。查詢語句如下:

Query 5. 加入總體彙總結果

 

 
SELECT
YEAR(OrderDate) AS OrderYear,
MONTH(OrderDate) AS OrderMonth,
SUM(SubTotal) AS Incomes
FROM Sales.SalesOrderHeader
GROUP BY
GROUPING SETS
(
YEAR(OrderDate), --1st grouping set
(YEAR(OrderDate),MONTH(OrderDate)), --2nd grouping set
() --3rd grouping set (grand total)
);
GO

 

 

 

結果如圖:

註意最下方的42行,年月都為null,這個查詢彙總了鄭鐵的所有收入,因為沒有進行任何分組。

註意,需要強調一個十強,一定要確保分組列欄位部位NULL,因此NULLS不能被用作分組列在GROUPING SETS中使用。如果非要那個為空欄位,需要使用 GROUPING 或者 GROUPING_ID 函數判斷是否NULL來自GROUPING SETS 操作符。

總結

本篇文章中,主要介紹如何使用另一種聚合查詢方式來實現多種分組聚合結果的合併。熟悉後你會發現這種方式對於總結彙總數據非常有幫助,大大提高了我們代碼的效率。

原文地址

 


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

-Advertisement-
Play Games
更多相關文章
  • 說到這兩個的差別我們想到的首先就應該是這兩個集合的性質有相對較大的區別,List就像是一個火車,ArrayList就像是自己家的小轎車,List對於裝載的事物有限制一開始必須在泛型定義好的事物,就是拉貨物的火車車廂中都幾乎是貨物, 而小汽車是自家的你想拉啥就拉啥,ArrayList就充當小轎車的角色 ...
  • "回到目錄" 環境 環境,對於開發來說就是部署的一種場景,你可以是調試場景,測試場景,生產場景,當然還可以有很多其它的場景,只要你的項目需要就可以自定義,微軟幫我們定義了三種標準的環境變數,下麵來說一下. 預設定義三種場景 1. Development 開發環境 appsetting.Develop ...
  • 1、Crond定義 crond是Linux系統中用來定期執行命令或指定程式的一種服務或軟體。 (1)linux系統自身定期執行的任務(輪詢系統日誌、備份數據等) (2)用戶執行的任務(定時更新同步時間、網站數據備份等) 2、Crond命令語法 定時任務的命令是crontab,其守護進程是crond( ...
  • NAME vim - Vi IMproved, a programmers text editor #vi的改進,一個程式文本編輯器 1、移動游標的方法 2、查找和替換 /word 向游標下麵尋找一個名為word的字元串,配合n,向下查找,N向上查找 3、刪除、複製和粘貼 dd 刪除游標所在的行 y ...
  • 介紹 Zabbix是一款能夠監控各種網路參數以及伺服器健康性和完整性的軟體。Zabbix使用靈活的通知機制,允許用戶為幾乎任何事件配置基於郵件的告警。這樣可以快速反饋伺服器的問題。基於已存儲的數據,Zabbix提供了出色的報告和數據可視化功能。這些功能使得Zabbix成為容量規劃的理想方案。 新版已 ...
  • Nagios->check_openmanage[Dell R7*] Nagios->check_openmanage[Dell R7*] 2014年11月13日 下午 07:44 2014年11月13日 下午 07:44 需求介紹: 透過Nagios監控Dell R7系列伺服器硬體狀態 環境信息: ...
  • 大概分兩步,先自定義字元串規則如去除空格特殊符號等等,再使用轉義,後面的語句一定要加上單引號。 ...
  • [1]介紹 [2]用戶模型 [3]加密 [4]驗證 [5]測試 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...