Pivot 和 UnPivot 实现行列转换
Pivot 语法:
table_source -- 表名称,即数据源 PIVOT( 聚合函数(value_column) -- value_column 要转换为 列值 的列名 FOR pivot_column -- pivot_column 指定要转换的列 IN(<column_list>) -- column_list 自定义的目标列名 )
create table #temp ( Name nvarchar(10) null, Course nvarchar(10) null, Score int null ) insert into #temp(Name,Course,Score) select '小李','语文','88' union select '小李','数学','79' union select '小李','英语','85' union select '小明','语文','79' union select '小明','数学','89' union select '小明','英语','87' union select '小红','语文','84' union select '小红','数学','76' union select '小红','英语','92' select * from #temp go
使用 Pivot 进行 行转列:
select a.Name 姓名,a.语文,a.数学,a.英语 from #temp pivot ( max(Score) -- 指定作为转换的列的值 的列名 for Course -- 指定要转换的列的列名 in(语文,数学,英语) -- 自定义的目标列名,即要转换列的不同的值作为列 )a
select a.Name 姓名,a.语文,a.数学,a.英语,b.SumScore 课程总分,b.AvgScore 课程平均分 from #temp pivot ( max(Score) -- 指定作为转换的列的值 的列名 for Course -- 指定要转换的列的列名 in(语文,数学,英语) -- 自定义的目标列名,即要转换列的不同的值作为列 )a, ( select t.Name,sum(t.Score) SumScore,cast(avg(t.Score) as decimal(18,2)) AvgScore from #temp t group by t.Name )b where a.Name=b.Name
UnPivot 语法:
table_source -- 表名称,即数据源 UNPIVOT( value_column -- value_column 要转换为 行值 的列名 FOR pivot_column -- pivot_column 指定要转换为指定的列 IN(<column_list>) -- column_list 目标列名 )
( Name nvarchar(10) null, Chinese int null, Math int null, English int null ) insert into #temp(Name,Chinese,Math,English) select '小李','88','79','85' union select '小明','79','89','87' union select '小红','84','76','92' select * from #temp go
使用 UnPivot 进行列转行:
select t.Name 姓名,t.Course 课程,t.Score 分数 from #temp unpivot ( Score for Course in(Chinese,Math,English) )t