SQL 查询横表变竖表

SQL 查询横表变竖表

 

/*
普通行列转换


假设有张学生成绩表(tb)如下:
Name Subject Result
张三 语文  74
张三 数学  83
张三 物理  93
李四 语文  74
李四 数学  84
李四 物理  94

*/

-------------------------------------------------------------------------
/*
想变成 
姓名         语文        数学        物理          
---------- ----------- ----------- ----------- 
李四         74          84          94
张三         74          83          93

*/

createtable tb
(
   Name    
varchar(10) ,
   Subject 
varchar(10) ,
   Result  
int
)

insertinto tb(Name , Subject , Result) values('张三' , '语文' , 74)
insertinto tb(Name , Subject , Result) values('张三' , '数学' , 83)
insertinto tb(Name , Subject , Result) values('张三' , '物理' , 93)
insertinto tb(Name , Subject , Result) values('李四' , '语文' , 74)
insertinto tb(Name , Subject , Result) values('李四' , '数学' , 84)
insertinto tb(Name , Subject , Result) values('李四' , '物理' , 94)
go

--静态SQL,指subject只有语文、数学、物理这三门课程。
select name 姓名,
  
max(case subject when'语文'then result else0end) 语文,
  
max(case subject when'数学'then result else0end) 数学,
  
max(case subject when'物理'then result else0end) 物理
from tb
groupby name
/*
姓名         语文        数学        物理          
---------- ----------- ----------- ----------- 
李四         74          84          94
张三         74          83          93

*/

--动态SQL,指subject不止语文、数学、物理这三门课程。
declare@sqlvarchar(8000)
set@sql='select Name as '+'姓名'
select@sql=@sql+' , max(case Subject when '''+ Subject +''' then Result else 0 end) ['+ Subject +']'
from (selectdistinct Subject from tb) as a
set@sql=@sql+' from tb group by name'
exec(@sql
/*
姓名         数学        物理        语文          
---------- ----------- ----------- ----------- 
李四         84          94          74
张三         83          93          74

*/

-------------------------------------------------------------------
/*加个平均分,总分
姓名         语文        数学        物理        平均分                总分          
---------- ----------- ----------- ----------- -------------------- ----------- 
李四         74          84          94          84.00                252
张三         74          83          93          83.33                250

*/

--静态SQL,指subject只有语文、数学、物理这三门课程。
select name 姓名,
  
max(case subject when'语文'then result else0end) 语文,
  
max(case subject when'数学'then result else0end) 数学,
  
max(case subject when'物理'then result else0end) 物理,
  
cast(avg(result*1.0asdecimal(18,2)) 平均分,
  
sum(result) 总分
from tb
groupby name
/*
姓名         语文        数学        物理        平均分                总分          
---------- ----------- ----------- ----------- -------------------- ----------- 
李四         74          84          94          84.00                252
张三         74          83          93          83.33                250

*/

--动态SQL,指subject不止语文、数学、物理这三门课程。
declare@sql1varchar(8000)
set@sql1='select Name as '+'姓名'
select@sql1=@sql1+' , max(case Subject when '''+ Subject +''' then Result else 0 end) ['+ Subject +']'
from (selectdistinct Subject from tb) as a
set@sql1=@sql1+' , cast(avg(result*1.0) as decimal(18,2)) 平均分,sum(result) 总分 from tb group by name'
exec(@sql1
/*
姓名         数学        物理        语文        平均分                总分          
---------- ----------- ----------- ----------- -------------------- ----------- 
李四         84          94          74          84.00                252
张三         83          93          74          83.33                250

*/

droptable tb    

---------------------------------------------------------
---------------------------------------------------------
/*
如果上述两表互相换一下:即

姓名 语文 数学 物理
张三 74  83  93
李四 74  84  94

想变成 
Name       Subject Result      
---------- ------- ----------- 
李四         语文      74
李四         数学      84
李四         物理      94
张三         语文      74
张三         数学      83
张三         物理      93

*/

createtable tb1
(
   姓名 
varchar(10) ,
   语文 
int ,
   数学 
int ,
   物理 
int
)

insertinto tb1(姓名 , 语文 , 数学 , 物理) values('张三',74,83,93)
insertinto tb1(姓名 , 语文 , 数学 , 物理) values('李四',74,84,94)

select*from
(
  
select 姓名 as Name , Subject ='语文' , Result = 语文 from tb1 
  
unionall
  select 姓名 as Name , Subject ='数学' , Result = 数学 from tb1
  
unionall
  select 姓名 as Name , Subject ='物理' , Result = 物理 from tb1
) t

orderby name , case Subject when'语文'then1when'数学'then2when'物理'then3when'总分'then4end

--------------------------------------------------------------------
/*加个平均分,总分
Name       Subject     Result               
---------- -------    -------------------- 
李四         语文      74.00
李四         数学      84.00
李四         物理      94.00
李四         平均分    84.00
李四         总分      252.00
张三         语文      74.00
张三         数学      83.00
张三         物理      93.00
张三         平均分    83.33
张三         总分      250.00

*/

select*from
(
  
select 姓名 as Name , Subject ='语文' , Result = 语文 from tb1 
  
unionall
  select 姓名 as Name , Subject ='数学' , Result = 数学 from tb1
  
unionall
  select 姓名 as Name , Subject ='物理' , Result = 物理 from tb1
  
unionall
  select 姓名 as Name , Subject ='平均分' , Result =cast((语文 + 数学 + 物理)*1.0/3asdecimal(18,2)) from tb1
  
unionall
  select 姓名 as Name , Subject ='总分' , Result = 语文 + 数学 + 物理 from tb1
) t

orderby name , case Subject when'语文'then1when'数学'then2when'物理'then3when'平均分'then4when'总分'then5end

droptable tb1

 

展开阅读全文

没有更多推荐了,返回首页