sql中行列互換問題

感覺還是蠻全的

/* 

標題:普通行列轉換(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 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章