sql查询 竖排变横排及横排变竖排显示 行列转换问题

阅读更多

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

create table tb
(
   Name    varchar2(10) ,
   Subject varchar2(10) ,
   Result  number
);
insert into tb(Name , Subject , Result) values('张三' , '语文' , 74)
insert into tb(Name , Subject , Result) values('张三' , '数学' , 83)
insert into tb(Name , Subject , Result) values('张三' , '物理' , 93)
insert into tb(Name , Subject , Result) values('李四' , '语文' , 74)
insert into tb(Name , Subject , Result) values('李四' , '数学' , 84)
insert into tb(Name , Subject , Result) values('李四' , '物理' , 94)

--静态SQL,指subject只有语文、数学、物理这三门课程。
select name 姓名,
  (case subject when '语文' then result else 0 end) 语文,
  (case subject when '数学' then result else 0 end) 数学,
  (case subject when '物理' then result else 0 end) 物理
from tb

case的括号前可加数据统计函数,如max,sum等
max(case subject when '语文' then result else 0 end) 语文--语文最高分
sum(case subject when '语文' then result else 0 end) 语文--语文成绩之和(适合竖排有重复列的情况)

--动态SQL,指subject不止语文、数学、物理这三门课程。
create or replace procedure test as
declare @sql varchar2(8000)
set @sql = 'select Name as ' + '姓名'
select @sql = @sql + ' , max(case Subject when ''' + Subject + ''' then Result else 0 end) [' + Subject + ']'
from (select distinct Subject from tb) as a
set @sql = @sql + ' from tb group by name'
exec(@sql);

加个平均分,总分

--静态SQL,指subject只有语文、数学、物理这三门课程。
select name 姓名,
  max(case subject when '语文' then result else 0 end) 语文,
  max(case subject when '数学' then result else 0 end) 数学,
  max(case subject when '物理' then result else 0 end) 物理,
  cast(avg(result*1.0) as decimal(18,2)) 平均分,
  sum(result) 总分
from tb
group by name

--动态SQL,指subject不止语文、数学、物理这三门课程。
declare @sql1 varchar(8000)
set @sql1 = 'select Name as ' + '姓名'
select @sql1 = @sql1 + ' , max(case Subject when ''' + Subject + ''' then Result else 0 end) [' + Subject + ']'
from (select distinct 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)

drop table tb;

---------------------------------------------------------
--如果上述两表互相换一下:即横排变竖排

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

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

create table tb1
(
   姓名 varchar2(10) ,
   语文 number ,
   数学 number ,
   物理 number
);
insert into tb1(姓名 , 语文 , 数学 , 物理) values('张三',74,83,93);
insert into tb1(姓名 , 语文 , 数学 , 物理) values('李四',74,84,94);

select * from
(
  select 姓名 as Name ,'语文' , 语文 from tb1
  union all
  select 姓名 as Name , '数学' ,数学 from tb1
  union all
  select 姓名 as Name , '物理' , 物理 from tb1
) t
order by name

drop table tb1;

以上在oralce 9i环境下编译通过。

 

以上是网上找的,但是实际运行是出现了多列,有0的情况,其实SQL语句要这样写的
select name 姓名,
  max(case subject when '语文' then result else 0 end) 语文,
  max(case subject when '数学' then result else 0 end) 数学,
  max(case subject when '物理' then result else 0 end) 物理
from tb group by  name;

结果才是这个:

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

你可能感兴趣的:(sql查询)