在輸出統計結果時可能需要將列變成行,而將聚合結果(如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...