PIVOT用於將列值旋轉爲列名(即行轉列),在SQL Server 2000能夠用聚合函數配合CASE語句實現sql
PIVOT的通常語法是:PIVOT(聚合函數(列) FOR 列 in (…) )AS P數據庫
完整語法:網絡
table_source PIVOT( 聚合函數(value_column) FOR pivot_column IN(<column_list>) )
UNPIVOT用於將列明轉爲列值(即列轉行),在SQL Server 2000能夠用UNION來實現函數
完整語法:code
table_source UNPIVOT( value_column FOR pivot_column IN(<column_list>) )
注意:PIVOT、UNPIVOT是SQL Server 2005 的語法,使用需修改數據庫兼容級別 在數據庫屬性->選項->兼容級別改成 90排序
典型實例ci
1、行轉列數學
一、創建表格io
if object_id ('tb') is not null drop table tb
gotable
create table tb ( 姓名 varchar(10), 課程 varchar(10), 分數 int ) insert into tb values ('張三','語文',74) insert into tb values('張三','數學',83) insert into tb values('張三','物理',93) insert into tb values('李四','語文',74) insert into tb values('李四','數學',84) insert into tb values('李四','物理',94)
go
select * from tb
go
姓名 課程 分數
張三 語文 74
張三 數學 83
張三 物理 93
李四 語文 74
李四 數學 84
李四 物理 94
二、使用SQL Server 2000靜態SQL
select姓名, max ( case 課程 when '語文' then 分數 else 0 end ) 語文, max ( case 課程 when '數學' then 分數 else 0 end ) 數學, max ( case 課程 when '物理' then 分數 else 0 end ) 物理 from tb group by 姓名
姓名 語文 數學 物理
李四 74 84 94
張三 74 83 93
三、使用SQL Server 2000動態SQL
--SQL SERVER 2000動態SQL,指課程不止語文、數學、物理這三門課程。(如下同)
--變量按sql語言順序賦值
declare@sqlvarchar(500) set@sql='select姓名' select@sql=@sql+',max(case課程when '''+課程+''' then分數else 0 end)['+課程+']' from(selectdistinct課程fromtb)a--同from tb group by課程,默認按課程名排序 set@sql=@sql+' from tb group by姓名' exec(@sql)
--使用isnull(),變量先肯定動態部分
declare@sqlvarchar(8000) select@sql=isnull(@sql+',','')+' max(case課程when '''+課程+''' then分數else 0 end) ['+課程+']' from(selectdistinct課程fromtb)asa set@sql='select姓名,'+@sql+' from tb group by姓名' exec(@sql)
姓名 數學 物理 語文
李四 84 94 74
張三 83 93 74
四、使用SQL Server 2005靜態SQL
select * from tb pivot ( max (分數) for 課程 in (語文,數學,物理) ) a
五、使用SQL Server 2005動態SQL
--使用stuff()
declare@sqlvarchar(8000) set@sql='' --初始化變量@sql select@sql=@sql+','+課程fromtbgroupby課程--變量多值賦值 set@sql=stuff(@sql,1,1,'')--去掉首個',' set@sql='select * from tb pivot (max(分數) for課程in ('+@sql+'))a' exec(@sql)
--或使用isnull()
declare@sqlvarchar(8000)
–-得到課程集合
select@sql=isnull(@sql+',','')+課程fromtbgroupby課程 set@sql='select * from tb pivot (max(分數) for課程in ('+@sql+'))a' exec(@sql)
2、行轉列結果加上總分、平均分
一、使用SQL Server 2000靜態SQL
--SQL SERVER 2000靜態SQL
select 姓名, max ( case 課程 when '語文' then 分數 else 0 end ) 語文, max ( case 課程 when '數學' then 分數 else 0 end ) 數學, max ( case 課程 when '物理' then 分數 else 0 end ) 物理, sum ( 分數 ) 總分, cast ( avg( 分數*1.0 ) as decimal(18,2) ) 平均分 from tb group by 姓名
姓名 語文 數學 物理 總分 平均分
李四 74 84 94 252 84.00
張三 74 83 93 250 83.33
二、使用SQL Server 2000動態SQL
--SQL SERVER 2000動態SQL
declare@sqlvarchar(500) set@sql='select姓名' select@sql=@sql+',max(case課程when '''+課程+''' then分數else 0 end)['+課程+']' from(selectdistinct課程fromtb)a set@sql=@sql+',sum(分數)總分,cast(avg(分數*1.0) as decimal(18,2)) 平均分from tb group by姓名' exec(@sql)
三、使用SQL Server 2005靜態SQL
select m.* , n.總分 , n.平均分 from ( select * from tb pivot ( max(分數) for 課程 in (語文,數學,物理) ) a ) m, ( select 姓名, sum (分數) 總分, cast( avg(分數*1.0) as decimal(18,2) ) 平均分 from tb group by 姓名 ) n where m.姓名 = n.姓名
四、使用SQL Server 2005動態SQL
--使用stuff()
declare@sqlvarchar(8000) set@sql='' --初始化變量@sql select@sql=@sql+','+課程fromtbgroupby課程--變量多值賦值 --同select @sql = @sql + ','+課程from (select distinct課程from tb)a set@sql=stuff(@sql,1,1,'')--去掉首個',' set@sql='select m.* , n.總分,n.平均分from (select * from (select * from tb) a pivot (max(分數) for課程in ('+@sql+')) b) m , (select姓名,sum(分數)總分, cast(avg(分數*1.0) as decimal(18,2))平均分from tb group by姓名) n where m.姓名= n.姓名' exec(@sql)
--或使用isnull()
declare@sqlvarchar(8000) select@sql=isnull(@sql+',','')+課程fromtbgroupby課程 set@sql='select m.* , n.總分,n.平均分from (select * from (select * from tb) a pivot (max(分數) for課程in ('+ @sql+')) b) m , (select姓名,sum(分數)總分, cast(avg(分數*1.0) as decimal(18,2))平均分from tb group by姓名) n where m.姓名= n.姓名' exec(@sql)
2、列轉行
一、創建表格
if object_id ('tb') is not null drop table tb
go
create table tb ( 姓名 varchar(10), 語文 int, 數學 int,物理 int ) insert into tb values ( '張三' ,74,83,93) insert into tb values ('李四',74,84,94)
go
select * from tb
go
姓名 語文 數學 物理
張三 74 83 93
李四 74 84 94
二、使用SQL Server 2000靜態SQL
--SQL SERVER 2000靜態SQL。
select * from ( select 姓名 , 課程 = '語文',分數 = 語文 from tb unionall select 姓名,課程='數學', 分數=數學 from tb unionall select 姓名,課程='物理',分數=物理 from tb ) t order by 姓名,case 課程 when '語文' then 1 when '數學' then 2 when '物理' then 3 end
姓名 課程 分數
李四 語文 74
李四 數學 84
李四 物理 94
張三 語文 74
張三 數學 83
張三 物理 93
二、使用SQL Server 2000動態SQL
--SQL SERVER 2000動態SQL。
--調用系統表動態生態。
declare@sqlvarchar(8000) select@sql=isnull(@sql+' union all ','')+' select姓名, [課程]=' +quotename(Name,'''')+' , [分數] = '+quotename(Name)+' from tb' fromsyscolumns whereName!='姓名'andID=object_id('tb')--表名tb,不包含列名爲姓名的其餘列 orderbycolid exec(@sql+' order by姓名')
go
三、使用SQL Server 2005靜態SQL
--SQL SERVER 2005動態SQL
select 姓名,課程,分數 from tb unpivot (分數 for 課程 in ( [語文],[數學],[物理] ) ) t
四、使用SQL Server 2005動態SQL
--SQL SERVER 2005動態SQL
declare@sqlnvarchar(4000) select@sql=isnull(@sql+',','')+quotename(Name) fromsyscolumns whereID=object_id('tb')andNamenotin('姓名') orderbyColid set@sql='select姓名,[課程],[分數] from tb unpivot ([分數] for [課程] in('+@sql+'))b' exec(@sql)
以上內容由網絡收集整合而來,非本人原創,感謝無數網友的貢獻。