sql中行列互换问题

来源:互联网 发布:淘宝招商条件 编辑:程序博客网 时间:2024/05/17 03:44

感觉还是蛮全的

/* 

标题:普通行列转换(version 2.0) 
问题:假学生成(tb)如下: 
姓名 程 分数 
三  74 
三 数学 83 
三 物理 93 
李四  74 
李四 数学 84 
李四 物理 94 
(得到如下): 
姓名 文 数学 物理 
---- ---- ---- ---- 
李四 74   84   94 
三 74   83   93 
------------------- 
*/ 
  
createtable tb(姓名 varchar(10) , 程 varchar(10) , 分数 int) 
insertinto tb values('三' , '文' , 74) 
insertinto tb values('三' , '数学' , 83) 
insertinto tb values('三' , '物理' , 93) 
insertinto tb values('李四' , '文' , 74) 
insertinto tb values('李四' , '数学' , 84) 
insertinto tb values('李四' , '物理' , 94) 
go 
  
--SQL SERVER 2000 SQL,程只有文、数学、物理门课程。(以下同) 
select姓名 as姓名 , 
 max(case程 when'文'then分数 else0end文, 
 max(case程 when'数学'then分数 else0end数学, 
 max(case程 when'物理'then分数 else0end物理 
from tb 
groupby姓名 
  
--SQL SERVER 2000 动态SQL,程不止文、数学、物理门课程。(以下同) 
declare@sqlvarchar(8000) 
set@sql='select 姓名 ' 
select@sql=@sql+' , max(case 程 when '''+程 +''' then 分数 else 0 end) ['+程 +']' 
from (selectdistinct程 from tb) as a 
set@sql=@sql+' from tb group by 姓名' 
exec(@sql
  
--SQL SERVER 2005 SQL 
select*from (select*from tb) a pivot (max(分数) for程 in (文,数学,物理)) b 
  
--SQL SERVER 2005 动态SQL 
declare@sqlvarchar(8000) 
select@sql=isnull(@sql+',' , ''+程 from tb groupby 
exec ('select * from (select * from tb) a pivot (max(分数) for 程 in ('+@sql+')) b') 
  
--------------------------------- 
  
/* 
问题:在上述果的基上加平均分,分,得到如下果: 
姓名 文 数学 物理 平均分 分 
---- ---- ---- ---- ------ ---- 
李四 74   84   94   84.00 252 
三 74   83   93   83.33 250 
*/ 
  
--SQL SERVER 2000 SQL 
select姓名 姓名, 
 max(case程 when'文'then分数 else0end文, 
 max(case程 when'数学'then分数 else0end数学, 
 max(case程 when'物理'then分数 else0end物理, 
 cast(avg(分数*1.0asdecimal(18,2)) 平均分, 
 sum(分数)  
from tb 
groupby姓名 
  
--SQL SERVER 2000 动态SQL 
declare@sqlvarchar(8000) 
set@sql='select 姓名 ' 
select@sql=@sql+' , max(case 程 when '''+程 +''' then 分数 else 0 end) ['+程 +']' 
from (selectdistinct程 from tb) as a 
set@sql=@sql+' , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 分 from tb group by 姓名' 
exec(@sql
  
--SQL SERVER 2005 SQL 
select m.* , n.平均分 , n.分 from 
(select*from (select*from tb) a pivot (max(分数) for程 in (文,数学,物理)) b) m, 
(select姓名 , cast(avg(分数*1.0asdecimal(18,2)) 平均分 , sum(分数) 分 from tb groupby姓名) n 
where m.姓名 = n.姓名 
  
--SQL SERVER 2005 动态SQL 
declare@sqlvarchar(8000) 
select@sql=isnull(@sql+',' , ''+程 from tb groupby 
exec ('select m.* , n.平均分 , n.分 from 
(select * from (select * from tb) a pivot (max(分数) for 程 in ('+@sql+')) b) m , 
(select 姓名 , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 分 from tb group by 姓名) n
where m.姓名 = n.姓名') 
  
droptable tb    
  
------------------ 
------------------ 
  
/* 
问题:如果上述两表互相一下:即表构和数据 
姓名 文 数学 物理 
 74  83  93 
李四 74  84  94 
(得到如下): 
姓名 程 分数 
---- ---- ---- 
李四  74 
李四 数学 84 
李四 物理 94 
三  74 
三 数学 83 
三 物理 93 
-------------- 
*/ 
  
createtable tb(姓名 varchar(10) , 文 int , 数学 int , 物理 int) 
insertinto tb values('三',74,83,93) 
insertinto tb values('李四',74,84,94) 
go 
  
--SQL SERVER 2000 SQL 
select*from 
( 
 select姓名 , 程 ='文' , 分数 =文 from tb 
 unionall 
 select姓名 , 程 ='数学' , 分数 =数学 from tb 
 unionall 
 select姓名 , 程 ='物理' , 分数 =物理 from tb 
) t 
orderby姓名 , case程 when'文'then1when'数学'then2when'物理'then3end 
  
--SQL SERVER 2000 动态SQL 
--用系动态 
declare@sqlvarchar(8000) 
select@sql=isnull(@sql+' union all ' , '' ) +' select 姓名 , [程] = '+quotename(Name , ''''+' , [分数] = '+quotename(Name) +' from tb' 
from syscolumns 
where name! = N'姓名'and ID =object_id('tb'--表名tb,不包含列名姓名的其它列 
orderby colid asc 
exec(@sql+' order by 姓名 ') 
  
--SQL SERVER 2005 动态SQL 
select姓名 , 程 , 分数 from tb unpivot (分数 for程 in([文] , [数学] , [物理])) t 
  
--SQL SERVER 2005 动态SQL,同SQL SERVER 2000 动态SQL 
  
-------------------- 
/* 
问题:在上述的果上加个平均分,分,得到如下果: 
姓名    分数 
---- ------ ------ 
李四    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 tb 
 unionall 
 select姓名 as姓名 , 程 ='数学' , 分数 =数学 from tb 
 unionall 
 select姓名 as姓名 , 程 ='物理' , 分数 =物理 from tb 
 unionall 
 select姓名 as姓名 , 程 ='平均分' , 分数 =cast((文 +数学 +物理)*1.0/3asdecimal(18,2)) from tb 
 unionall 
 select姓名 as姓名 , 程 ='分' , 分数 =文 +数学 +物理 from tb 
) t 
orderby姓名 , case程 when'文'then1when'数学'then2when'物理'then3when'平均分'then4when'分'then5end 

droptable tb 
原创粉丝点击