关于SQLServer数据库大量数据行列转置解决方法( 二 )

问题2:如果上述两表互相换一下:即表结构和数据为:
姓名 语文 数学 物理
张三 748393
李四 748494
想变成(得到如下结果):
姓名 课程 分数
---- ---- ----
李四 语文 74
李四 数学 84
李四 物理 94
张三 语文 74
张三 数学 83
张三 物理 93
--------------
解决方法如下所示:
create table tb(姓名 varchar(10) , 语文 int , 数学 int , 物理 int)insert into tb values('张三',74,83,93)insert into tb values('李四',74,84,94)go--SQL SERVER 2000 静态SQL 。 select * from(select 姓名 , 课程 = '语文' , 分数 = 语文 from tbunion allselect 姓名 , 课程 = '数学' , 分数 = 数学 from tbunion allselect 姓名 , 课程 = '物理' , 分数 = 物理 from tb) torder by 姓名 , case 课程 when '语文' then 1 when '数学' then 2 when '物理' then 3 end--SQL SERVER 2000 动态SQL 。 --调用系统表动态生态 。 declare @sql varchar(8000)select @sql = isnull(@sql + ' union all ' , '' ) + ' select 姓名 , [课程] = ' + quotename(Name , '''') + ' , [分数] = ' + quotename(Name) + ' from tb'from syscolumnswhere name! = N'姓名' and ID = object_id('tb') --表名tb , 不包含列名为姓名的其它列order by colid ascexec(@sql + ' order by 姓名 ')--SQL SERVER 2005 动态SQL 。 select 姓名 , 课程 , 分数 from tb unpivot (分数 for 课程 in([语文] , [数学] , [物理])) t--SQL SERVER 2005 动态SQL , 同SQL SERVER 2000 动态SQL 。 问题3:在上述的结果上加个平均分 , 总分 , 得到如下结果:
姓名 课程 分数
---- ------ ------
李四 语文 74.00
李四 数学 84.00
李四 物理 94.00
李四 平均分 84.00
李四 总分 252.00
张三 语文 74.00
张三 数学 83.00
张三 物理 93.00
张三 平均分 83.33
张三 总分 250.00
解决方法如下所示:
select * from(select 姓名 as 姓名 , 课程 = '语文' , 分数 = 语文 from tbunion allselect 姓名 as 姓名 , 课程 = '数学' , 分数 = 数学 from tbunion allselect 姓名 as 姓名 , 课程 = '物理' , 分数 = 物理 from tbunion allselect 姓名 as 姓名 , 课程 = '平均分' , 分数 = cast((语文 + 数学 + 物理)*1.0/3 as decimal(18,2)) from tbunion allselect 姓名 as 姓名 , 课程 = '总分' , 分数 = 语文 + 数学 + 物理 from tb) torder by 姓名 , case 课程 when '语文' then 1 when '数学' then 2 when '物理' then 3 when '平均分' then 4 when '总分' then 5 enddrop table tb--> 生成测试数据: #DB_infoif object_id('tempdb.dbo.#DB_info') is not null drop table #DB_infocreate table #DB_info (sid int,name nvarchar(4),sex nvarchar(2))insert into #DB_infoselect 1,'李明','男' union allselect 2,'王军','男' union allselect 3,'李敏','女'--> 生成测试数据: #db_scoresif object_id('tempdb.dbo.#db_scores') is not null drop table #db_scorescreate table #db_scores (sid int,type nvarchar(4),scores int)insert into #db_scoresselect 1,'语文',80 union allselect 1,'数学',90 union allselect 2,'语文',85 union allselect 2,'数学',90 union allselect 3,'语文',75 union allselect 3,'数学',85declare @sql nvarchar(4000)set @sql='select a.sid,a.name,a.sex'select @sql=@sql+',max(case when b.type='''+type+''' then b.scores else 0 end) ['+type+']'from (select distinct type from #db_scores) texec (@sql+' from #DB_info a left outer join #db_scores b on a.sid=b.sid group by a.sid,a.name,a.sex')