SqlServer行转列(PIVOT),列转行(UNPIVOT)总结
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SqlServer行转列(PIVOT),列转行(UNPIVOT)总结相关的知识,希望对你有一定的参考价值。
PIVOT用于将列值旋转为列名(即行转列)
语法:
table_source PIVOT( 聚合函数(value_column) FOR pivot_column IN(<column_list>) )
UNPIVOT用于将列明转为列值(即列转行)
语法:
table_source UNPIVOT( value_column FOR pivot_column IN(<column_list>) )
注意:PIVOT、UNPIVOT是SQL Server 2005的语法,使用需修改数据库兼容级别
在数据库属性->选项->兼容级别改为
90
一、行转列
1、建立表格
ifobject_id(‘tb‘)isnotnulldroptabletb go 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
2、使用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姓名
3、使用SQL Server 2000动态SQL
[email protected](500) [email protected]=‘select姓名‘ [email protected][email protected]+‘,max(case课程when ‘‘‘+课程+‘‘‘ then分数else 0 end)[‘+课程+‘]‘ from(selectdistinct课程fromtb)a--同from tb group by课程,默认按课程名排序 [email protected][email protected]+‘ from tb group by姓名‘ exec(@sql)
--使用isnull(),变量先确定动态部分
[email protected](8000) [email protected]=isnull(@sql+‘,‘,‘‘)+‘ max(case课程when ‘‘‘+课程+‘‘‘ then分数else 0 end) [‘+课程+‘]‘ from(selectdistinct课程fromtb)asa [email protected]=‘select姓名,‘[email protected]+‘ from tb group by姓名‘ exec(@sql)
4、使用SQL Server 2005静态SQL
select*fromtb pivot(max(分数)for课程in(语文,数学,物理))a
5、使用SQL Server 2005动态SQL
--使用stuff() [email protected](8000) [email protected]=‘‘ --初始化变量@sql [email protected][email protected]+‘,‘+课程fromtbgroupby课程--变量多值赋值 [email protected]=stuff(@sql,1,1,‘‘)--去掉首个‘,‘ [email protected]=‘select * from tb pivot (max(分数) for课程in (‘[email protected]+‘))a‘ exec(@sql) --或使用isnull() [email protected](8000) –-获得课程集合 [email protected]=isnull(@sql+‘,‘,‘‘)+课程fromtbgroupby课程 [email protected]=‘select * from tb pivot (max(分数) for课程in (‘[email protected]+‘))a‘ exec(@sql)
二、行转列结果加上总分、平均分
1、使用SQL Server 2000静态SQL
select姓名, max(case课程when‘语文‘then分数else0end)语文, max(case课程when‘数学‘then分数else0end)数学, max(case课程when‘物理‘then分数else0end)物理, sum(分数)总分, cast(avg(分数*1.0)asdecimal(18,2))平均分 fromtb groupby姓名
2、使用SQL Server 2000动态SQL
--SQL SERVER 2000动态SQL [email protected](500) [email protected]=‘select姓名‘ [email protected][email protected]+‘,max(case课程when ‘‘‘+课程+‘‘‘ then分数else 0 end)[‘+课程+‘]‘ from(selectdistinct课程fromtb)a [email protected][email protected]+‘,sum(分数)总分,cast(avg(分数*1.0) as decimal(18,2)) 平均分from tb group by姓名‘ exec(@sql)
3、使用SQL Server 2005静态SQL
selectm.*,n.总分,n.平均分 from (select*fromtb pivot(max(分数)for课程in(语文,数学,物理))a)m, (select姓名,sum(分数)总分,cast(avg(分数*1.0)asdecimal(18,2))平均分 fromtb groupby姓名)n wherem.姓名=n.姓名
4、使用SQL Server 2005动态SQL
[email protected](8000) [email protected]=‘‘ --初始化变量@sql [email protected][email protected]+‘,‘+课程fromtbgroupby课程--变量多值赋值 --同select @sql = @sql + ‘,‘+课程from (select distinct课程from tb)a [email protected]=stuff(@sql,1,1,‘‘)--去掉首个‘,‘ [email protected]=‘select m.* , n.总分,n.平均分from (select * from (select * from tb) a pivot (max(分数) for课程in (‘[email protected]+‘)) b) m , (select姓名,sum(分数)总分, cast(avg(分数*1.0) as decimal(18,2))平均分from tb group by姓名) n where m.姓名= n.姓名‘ exec(@sql) --或使用isnull() [email protected](8000) [email protected]=isnull(@sql+‘,‘,‘‘)+课程fromtbgroupby课程 [email protected]=‘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)
二、列转行
1、建立表格
ifobject_id(‘tb‘)isnotnulldroptabletb go createtabletb(姓名varchar(10),语文int,数学int,物理int) insertintotbvalues(‘张三‘,74,83,93) insertintotbvalues(‘李四‘,74,84,94) go select*fromtb
2、使用SQL Server 2000静态SQL
--SQL SERVER 2000静态SQL。 select*from ( select姓名,课程=‘语文‘,分数=语文fromtb unionall select姓名,课程=‘数学‘,分数=数学fromtb unionall select姓名,课程=‘物理‘,分数=物理fromtb ) t orderby姓名,case课程when‘语文‘then1when‘数学‘then2when‘物理‘then3end
2、使用SQL Server 2000动态SQL
--SQL SERVER 2000动态SQL。 --调用系统表动态生态。 [email protected](8000) [email protected]=isnull(@sql+‘ union all ‘,‘‘)+‘ select姓名, [课程]=‘ +quotename(Name,‘‘‘‘)+‘ , [分数] = ‘+quotename(Name)+‘ from tb‘ fromsyscolumns whereName!=‘姓名‘andID=object_id(‘tb‘)--表名tb,不包含列名为姓名的其他列 orderbycolid exec(@sql+‘ order by姓名‘)
3、使用SQL Server 2005静态SQL
--SQL SERVER 2005动态SQL select姓名,课程,分数fromtb unpivot (分数for课程in([语文],[数学],[物理])) t
4、使用SQL Server 2005动态SQL
--SQL SERVER 2005动态SQL [email protected](4000) [email protected]=isnull(@sql+‘,‘,‘‘)+quotename(Name) fromsyscolumns whereID=object_id(‘tb‘)andNamenotin(‘姓名‘) orderbyColid [email protected]=‘select姓名,[课程],[分数] from tb unpivot ([分数] for [课程] in(‘[email protected]+‘))b‘ exec(@sql)
以上是关于SqlServer行转列(PIVOT),列转行(UNPIVOT)总结的主要内容,如果未能解决你的问题,请参考以下文章