有时候会碰到行转列的需求(也就是将列的值作为列名称),通常我都是用 CASE END + 聚合函数来实现的。
如下:
declare @t table(StudentName nvarchar(20), Subject nvarchar(20), Score int) Insert into @t (StudentName,Subject,Score) values ( "学生A", "中文", 80 );Insert into @t (StudentName,Subject,Score) values ( "学生A", "数学", 78 );Insert into @t (StudentName,Subject,Score) values ( "学生A", "英语", 92 );Insert into @t (StudentName,Subject,Score) values ( "学生B", "中文", 89 );Insert into @t (StudentName,Subject,Score) values ( "学生B", "数学", 87 );Insert into @t (StudentName,Subject,Score) values ( "学生B", "英语", 75 );Insert into @t (StudentName,Subject,Score) values ( "学生C", "中文", 92 );Insert into @t (StudentName,Subject,Score) values ( "学生C", "数学", 74 );Insert into @t (StudentName,Subject,Score) values ( "学生C", "英语", 65 );Insert into @t (StudentName,Subject,Score) values ( "学生D", "中文", 79 );Insert into @t (StudentName,Subject,Score) values ( "学生D", "数学", 83 );Insert into @t (StudentName,Subject,Score) values ( "学生D", "英语", 81 );Insert into @t (StudentName,Subject,Score) values ( "学生E", "中文", 73 );Insert into @t (StudentName,Subject,Score) values ( "学生E", "数学", 84 );Insert into @t (StudentName,Subject,Score) values ( "学生E", "英语", 93 );Insert into @t (StudentName,Subject,Score) values ( "学生F", "中文", 79 );Insert into @t (StudentName,Subject,Score) values ( "学生F", "数学", 86 );Insert into @t (StudentName,Subject,Score) values ( "学生F", "英语", 84 );select StudentName,sum(case when Subject = N"中文" then Score else 0 end) Chinese,sum(case when Subject = N"数学" then Score else 0 end) Math,sum(case when Subject = N"英语" then Score else 0 end) Engilsh from @t group by StudentName
今天看到一个新的写法,pivot 可以实现相同的功能(2005才开始支持)。
pivot 的语法为:table_sourcepivot(聚合函数(value_column) pivot_column for (columnlist))稍微解释一下:
table_source:是我们要进行转换的表。
pivot_column: 就是要进行行转列的列名。
value_column:是转换后列的值。columnlist 是要生成的列。
同样是上面的例子,使用pivot 可以这样写得到同样的结果:
select StudentName,[中文] Chinese,[数学] Math,[英语] English from(select * from @t) t1pivot (sum(Score) for Subject in([中文],[英语],[数学])) t2
与之对应的 unpivot 就是列转行了(列名作为值),
unpivot 的语法为:
table_sourceunpivot(value_column ubpivot_column for(columnlist))参数的意义与pivot 是一样的。这里我们可以简单的把刚刚转后的再转回去,这样就得到原来的表了:
select StudentName,Subject,Score from(select * from @t) t1pivot (sum(Score) for Subject in([中文],[英语],[数学])) t2unpivot (Score for Subject in([中文],[英语],[数学])) t3
以上就是本文的全部内容,希望对大家学习实现SQLServer行列互转有所帮助。