SQL SERVER中ROLLUP 運算子的用法

2021-06-19 17:02:27 字數 2603 閱讀 7578

問題的提出: 

現有表a,內容如下:

編碼  倉庫 

數量01 

a  6

01  b 

702 

a  8

02  b  9

現在想按編碼查詢出這種格式:

--------------------

01  a 

601 

b  7

彙總小計: 

1302 

a  8

02  b 

9彙總小計: 

17 問:該如何實現?

乍一看,好像很容易,用group by好像能實現?但仔細研究下去,你又會覺得group by也是無能為力,總欠缺點什麼,無從下手。那麼,到底該如何做呢?別急,sql server早就幫我們做好了,下面,跟我來。

首先,讓我們來看一段話:

在生成包含小計和合計的報表時,rollup 運算子很有用。rollup 運算子生成的結果集類似於 cube 運算子所生成的結果集。

========================

cube 運算子生成的結果集是多維資料集。多維資料集是事實資料的擴充套件,事實資料即記錄個別事件的資料。擴充套件建立在使用者打算分析的列上。這些列被稱為維。多維資料集是乙個結果集,其中包含了各維度的所有可能組合的交叉**。

cube 運算子在 select 語句的 group by 子句中指定。該語句的選擇列表應包含維度列和聚合函式表示式。group by 應指定維度列和關鍵字 with cube。結果集將包含維度列中各值的所有可能組合,以及與這些維度值組合相匹配的基礎行中的聚合值。

========================= 

cube 和 rollup 之間的區別在於: 

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

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

看完以上的這段話,悟出了什麼沒有?如果沒有,那麼……嘿嘿,你的悟性還不夠喲,離「三花棸頂」還早著呢:)。接下來我們再看一段(注意喲,答案馬上就揭曉了):

select 編碼, 倉庫, sum(數量) as 數量

from a

group by 編碼, 倉庫 with rollup

--關鍵就是後面的with rollup

--當然,你也可以用with cube,但是結果會有點不大一樣

可能看完上面這段你還是覺得「雲裡霧裡」,摸不著頭腦。實在不明白也沒關係,自己動手做。

首先:建乙個上面所說的a表,輸入幾行資料;

接著:開啟你的sql server查詢分析器,連上包含你上面所建a表的伺服器,選擇包含該錶的資料庫;

然後:copy上面這段sql 語句,paste到查詢分析器中,按f5,怎麼樣?看到下面出來了什麼?是不是和我下面的一樣?

編碼 倉庫 

數量01 

a   6

01  b 

701   

null  13

02  a 

802 

b  9

02   

null  17

null 

null  30

--如果你用的是with cube,結果集的後面還會多出兩條(如果你也只是輸入示例中的幾行資料的話):

null 

a  14

null 

b  16

咦!奇怪,結果中怎麼有那麼多「null」值?哈,別急,這幾行正是我們所要的彙總資料行,不難看出:

01 null 13正是對編碼為01的所有倉庫中的數量的彙總;02 null 17是對編碼為02的所有倉庫的數量的彙總;

null null 30是對所有資料行數量的彙總。

如何?答案出來了吧?是不是很簡單呢?當然,上面還有點美中不足,那就是有好多「null」的存在。如何去掉這些無意義的null呢?下面我們再進行優化。

1、用grouping替換null值

select case when (grouping(編碼) = 1) then 'all'

else isnull(編碼, 'unknown')

end as 編碼,

case when (grouping(倉庫) = 1) then 'all'

else isnull(倉庫, 'unknown')

end as 倉庫,

sum(數量) as 數量

from a

group by 編碼, 倉庫 with rollup

--適當的運用case函式

結果我這裡就不寫了,就是把上面的「null」值全部換成「all」字串

2、利用程式做進一步的優化

//通常為了顯示上的需要,我們必須對以上sql語句生成的結果做一些優化,下面給出自然語言描述:

while(未到達最後一條記錄){

if 編碼值不為all而倉庫值為all

{將編碼值用「小計:」替換,將倉庫值用""替換;

將這一行的顏色標示為灰色;

}else 編碼值為all倉庫值也為all

{將編碼值用「總計:」替換,將倉庫值用""替換;

將這一行的著色標示為淡綠色;

}指標移到下一條;}

//當然,你盡可以發揮你的想象,把**打扮得漂漂亮亮的,我就不再羅嗦了。

sqlserver 中Cube,rollup的使用

一 select from cj 1張三語文80.0 2張三數學90.0 3張三物理85.0 4李四語文85.0 5李四數學92.0 6李四物理82.0 二 select name,sum result from cj group by name 李四259.0 張三255.0 三 select n...

sql server 中語法校驗

在今天的培訓考試過程中,我提出乙個擴充套件題,要求對提交的sql進行語法校驗.其實這個題很簡單,根本不需要用正規表示式去做語法分析,可以直接使用sql server自帶的功能.不多說,上 alter proc sp checksql sql varchar 8000 error varchar ma...

SQL Server中的查詢

本博文簡單介紹一下sql server中常用的幾類查詢及相關使用的方法。一 executescalar方法獲取單一值 executescalar方法是sqlcommand類的方法之一,執行查詢,並返回查詢所返回的結果集中的第一行第一列。csharp view plain copy print cla...