分享

Oracle中纵表转横表(行列转换)示例

 双氧菌 2018-10-09
普通行列转换
假设有张学生成绩表(tb)如下:
Name Subject Result
张三 语文  74
张三 数学  83
张三 物理  93
李四 语文  74
李四 数学  84
李四 物理  94
*/


-------------------------------------------------------------------------
/*

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

createtabletb
(
   Name   
varchar(10) ,
   Subject
varchar(10) ,
   Result 
int
)

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

--静态SQL,指subject只有语文、数学、物理这三门课程。
selectname 姓名,
 
max(casesubject when'语文'thenresult else0end) 语文,
 
max(casesubject when'数学'thenresult else0end) 数学,
 
max(casesubject when'物理'thenresult else0end) 物理
fromtb
groupbyname
/*
姓名         语文        数学        物理         
---------- ----------- ----------- -----------
李四         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(selectdistinctSubject fromtb) asa
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只有语文、数学、物理这三门课程。
selectname 姓名,
 
max(casesubject when'语文'thenresult else0end) 语文,
 
max(casesubject when'数学'thenresult else0end) 数学,
 
max(casesubject when'物理'thenresult else0end) 物理,
 
cast(avg(result*1.0) asdecimal(18,2)) 平均分,
 
sum(result) 总分
fromtb
groupbyname
/*
姓名         语文        数学        物理        平均分                总分         
---------- ----------- ----------- ----------- -------------------- -----------
李四         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(selectdistinctSubject fromtb) asa
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
*/

droptabletb   

---------------------------------------------------------
--
-------------------------------------------------------
/*

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

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

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

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

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

select*from
(
 
select姓名 asName , Subject ='语文', Result =语文 fromtb1
 
unionall
 
select姓名 asName , Subject ='数学', Result =数学 fromtb1
 
unionall
 
select姓名 asName , Subject ='物理', Result =物理 fromtb1
) t
orderbyname , caseSubject 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姓名 asName , Subject ='语文', Result =语文 fromtb1
 
unionall
 
select姓名 asName , Subject ='数学', Result =数学 fromtb1
 
unionall
 
select姓名 asName , Subject ='物理', Result =物理 fromtb1
 
unionall
 
select姓名 asName , Subject ='平均分', Result =cast((语文 +数学 +物理)*1.0/3asdecimal(18,2)) fromtb1
 
unionall
 
select姓名 asName , Subject ='总分', Result =语文 +数学 +物理 fromtb1
) t
orderbyname , caseSubject when'语文'then1when'数学'then2when'物理'then3when'平均分'then4when'总分'then5end

droptabletb1

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多