1. 程式人生 > >SQL2008如何將多行轉換成多列

SQL2008如何將多行轉換成多列

SQL2008中有兩個函式:

  • pivot
  • unpivot

1.pivot可實現資料表的列轉行

語法如下:

select * from table pivot( 聚合函式(<列名1>) for  <列名2> in(<轉換的行中列2的值1,轉換的行中列2的值2,,...>))

例:

declare @temptable table([name] varchar(100),[saletype] varchar(100),[total] decimal(19,2)) 
insert into @temptable([name],[saletype],[total])
select '客戶A','商品A','100'
union all
select '客戶A','商品A','100'
union all
select '客戶A','商品B','200'
union all
select '客戶B','商品A','100'
union all
select '客戶B','商品B','300'
union all
select '客戶C','商品C','400'


select * from @temptable pivot(sum(total) for [saletype] in (商品A,商品B,商品C)) as pvt

這個方法,可以把某一列的值<列名1>求合後按照<列名2>轉換到行上,行上的列名分別為in後面(列名2中的值)中的值,這個方法只能轉換一列

2.unpivot可實現資料表的行轉列

語法如下:

select * from table unpivot(<轉換後的值> for <轉換後的列> in (<需要轉換的列1,需要轉換的列2,...>))

declare @temptable1 table([name] varchar(100),total1 decimal(19,2),total2 decimal(19,2),total3 decimal(19,2),total4 decimal(19,2))
insert into @temptable1
select 'A',1,2,3,4
union all
select 'B',11,22,33,44

select [name],[n],[v] from @temptable1
unpivot(v for n in(total1,total2,total3,total4)) a

注意:在in後面()中的值,是不允許重複的。

pivot函式只能把一列的值轉到行上去,但現在有一個表如下

declare @temptable2 table([name] varchar(100),dateday varchar(20),qty decimal(19,2),total decimal(19,2))
insert into @temptable2
select 'A','1月1號',20,200
union all
select 'A','2月2號',10,100
union all
select 'A','3月3號',20,200
union all
select 'B','2月1號',10,100
union all
select 'B','1月1號',20,500
union all
select 'C','2月1號',10,100
union all
select 'C','2月2號',100,1000
現在一行有有兩列,一個是qty,一個是total如果才能把這兩列的轉換到一行上去,現在用pivot好像不行,因為他只能轉換一列,現在可以看一下上面的資料,應該按到dataday來轉換,但又需要轉換兩個值。現在可以考慮先用unpivot函式先把行換成列,後再用pivot把列轉成行。
select * from (
select [name],dateday + n as columname,v from @temptable2 unpivot(v for n in (qty,total)) a
) b pivot(sum(v) for [columname] 
in ([1月1號qty],[1月1號total],[2月2號qty],[2月2號total],[3月3號qty],[3月3號total],
[2月1號qty],[2月1號total])) as c

這個地方還需要注意,有可能你的資料庫沒有設定相容運用pivot和unpivot會報錯,這個地方把SQL2008設定成

exec sp_dbcmptlevel DBName,100

DBName為對應的資料庫名