將聚合記錄集逆時針和順時針旋轉90度

2021-05-08 04:19:37 字數 3414 閱讀 7057

在輸出統計結果時可能需要將列變成行,而將聚合結果(如count、sum)作為記錄的第一行,先看如下的sql語句:

declare

@ttable

(name

varchar

(20))

insert

@tselect

'abc

'union

allselect

'***

'union

allselect

'***

'union

allselect

'ttt

'select

*from

@t在執行上面的sql語句後,會輸出如圖1所示的記錄集。

圖1上圖顯示的是乙個普通的記錄集,如果要統計name欄位的每個值的重複數,需要進行分組,如下面的sql如示:

select

count

(name)

asc ,name 

from

@tgroup

byname

執行上面的sql語句後的查詢結果如圖2所示。

圖2如果我們有乙個需求,需要如圖3所示的聚合結果。

圖3從圖3可以看出,查詢結果正好是圖2的結果逆時針旋轉90度,也就是說,name列的值變成了列名,而c列的值變成了第一行的記錄。圖2所示的c和name欄位消失了。

當然,要達到這個結果並不困難,看如下的sql語句:

select

(select

count

(name)

from

@twhere

name='

abc'

) as

abc,

(select

count

(name)

from

@twhere

name='

ttt'

) as

***,

(select

count

(name)

from

@twhere

name='

***'

) as

ttt上面的sql語句會出輸出如圖3的查詢結果。但這裡有個問題,上面的sql語句是列舉了name列所有可能的值,在本例中只有三個值('abc','ttt','***'),這非常好列舉,但如果有很多值,sql語句會變得非常長,非常不利於編寫。當然,可以通過程式設計的方式自動生成,但最終結果仍然會生成很長的sql語句。

為了解決這個問題,在sql server2005中提供了乙個pivot函式,該函式可以很容易地輸出如圖3所示的記錄集,如下面的sql語句所示:

select

*from

@tpivot(

count

(name)

forname in(

[abc],

[ttt],

[***

]))

在執行上面的sql語句同樣可以獲得圖3所示的查詢結果。實際上,pivot函式也起到了分組的作用。在使用pivot函式時應注意如下幾點:

1. pivot

函式需要指定聚合函式,如count、sum等,for關鍵字和聚合函式都要使用需要聚合的欄位名,在本例中是name。

2. in

關鍵字負責指定每組需要聚合的值,用[...]將這些值括起來。實際上,這些值也相當於我們第一種聚合方法中的where條件,例如,where name='abc'、where name='ttt',當然,這些值也是輸出記錄集的列名。

3. 在最後要為pivot函式起乙個別名。

雖然當要聚合的值很多時(或不確定),也需要動態生成sql語句,但使用pivot函式的sql語句卻短很多。

如果我們還有乙個需求,要將圖3的結果變成圖2的結果,也就是順時針旋轉90度,仍然以c和name作為欄位名。也許方法很多,但sql server2005提供了乙個unpivot函式,該函式是pivot函式的逆過程。也就是將記錄集順時針旋轉90度,先看下面的sql語句:

declare

@ttable

(name

varchar

(20))

insert

@tselect

'abc

'union

allselect

'***

'union

allselect

'***

'union

allselect

'ttt';

with

tt as

(select

*from

@tpivot(

count

(name)

forname in(

[abc],

[ttt],

[***

])) p)

select

*from

tt上面的sql語句將輸出如圖3所示的結果。如果將最後一條sql語句(select * from tt)換成如下的sql語句,將輸出如圖2所示的結果。

select

*from

tt  unpivot([c

]for

name in(

[abc],

[***],

[ttt

])) p

要注意的是,[c]中的c表示聚合結果列的欄位名,name表示要聚合列的欄位名,這兩個值可以是任意滿足欄位名命名規則的字串, [abc] ,[***],[ttt]分別是圖3所示的記錄集的欄位名,這些值必須一致。執行下面的sql語句將獲得圖4的輸出結果。

select

*from

tt  unpivot(

[統計值

]for

統計名 in(

N N矩陣旋轉問題 順時針,逆時針

方法一 對於矩陣旋轉可以將其分塊,具體來說就是分為 上 下 左 右 四個部分。比如將其順時針旋轉90度,可以先把上部分儲存留用,然後把左部分賦值給上部分 此時上部分已經有備份留用的了 下部分賦值給左部分,右部分賦值給下部分,儲存的上部分的備份賦值給右部分。簡言之,左 上,下 左,右 下,儲存 右。上...

unity 跟隨滑鼠 順時針或逆時針旋轉

private bool m isfirst true 用於記錄第一幀按下滑鼠時滑鼠的位置,便於計算 private vector3 m currentpos 記錄當前幀滑鼠所在位置 private bool m isclockwise 是否順時針 private float m roundvalu...

由內向外順時針旋轉佇列 逆時針旋轉佇列

如下 include using namespace std int max int n1,int n2 int abs int x int spiral int x,int y 根據座標得出當前值 else if x c 左邊 else if y c 下邊 else 右邊 x c void spi...