sql query vertical to horizontal and horizontal to vertical to display row and column conversion problems

Suppose there is a student transcript (tb) as follows:
Name Subject Result
Zhang Sanwen 74
Zhang San Math 83
Zhang San Physics 93
Li Si Language 74
Li Si Math 84
Li Si Physics 94
------------ -------------------------------------------------- -----------
Want to be
Name Language Mathematics Physics         
------------ ------------- ----------- -------------
Li Si 74 84 94
Zhang San 74 83 93

create table tb
(
   Name varchar2(10) ,
   Subject varchar2(10) ,
   Result number
);
insert into tb(Name , Subject , Result) values('Zhang San' , 'Language' , 74)
insert into tb(Name , Subject ) , Result) values('Zhang San' , 'Math' , 83)
insert into tb(Name , Subject , Result) values('Zhang San' , 'Physics' , 93)
insert into tb(Name , Subject , Result) values ('Li Si' , 'Wuwen' , 74)
insert into tb(Name , Subject , Result) values('Li Si' , 'Mathematics' , 84)
insert into tb(Name , Subject , Result) values('Li Si ' ' , 'Physics' , 94)

--Static SQL means that the subject has only three courses: Chinese, mathematics, and physics.
select name name,
  (case subject when 'language' then result else 0 end) language,
  (case subject when 'math' then result else 0 end) math,
  (case subject when 'physics' then result else 0 end) physics
from tb

Data statistics functions can be added before the brackets of the case, such as max, sum, etc.
max(case subject when 'Chinese' then result else 0 end) Chinese--Chinese highest score
sum(case subject when 'Chinese' then result else 0 end) Chinese --Sum of Chinese grades (suitable for vertical rows with repeated columns)

--Dynamic SQL means that the subject is not limited to the three courses of Chinese, mathematics, and physics.
create or replace procedure test as
declare @sql varchar2(8000)
set @sql = 'select Name as ' + 'Name'
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);

Add an average score to the total score

--Static SQL means that the subject has only three courses: Chinese, mathematics, and physics.
select name Name,
  max(case subject when 'Chinese' then result else 0 end) Chinese,
  max(case subject when 'Math' then result else 0 end) Mathematics,
  max(case subject when 'Physics' then result else 0 end) Physics,
  cast(avg(result*1.0) as decimal(18,2)) average score,
  sum(result) total score
from tb
group by name

--Dynamic SQL means that the subject is not limited to the three courses of Chinese, mathematics, and physics.
declare @sql1 varchar(8000)
set @sql1 = 'select Name as ' + 'Name'
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)) average score, sum(result) total Divide from tb group by name'
exec(@sql1)

drop table tb;

-------------------------------------------------- ------- --If
the above two tables are replaced with each other: that is, the horizontal row becomes the vertical row

Name Language Mathematics Physics
Zhang San 74 83 93
Li Si 74 84 94

Want to become
Name Subject Result     
---------- ------- -------------
Li Si Language 74
Li Si Math 84
Li Si Physics 94
Zhang San Chinese 74
Zhang San Mathematics 83
Zhang San Physics 93

create table tb1
(
   name varchar2(10) ,
   language number ,
   math number ,
   physics number
);
insert into tb1 (name, language, mathematics, physics) values('Zhang San',74,83,93);
insert into tb1( Name, Chinese, Math, Physics) values('Li Si',74,84,94);

select * from
(
  select name as Name , 'language' , language from tb1
  union all
  select name as Name , 'math' , math from tb1
  union all
  select name as Name , 'physics' , physics from tb1
) t
order by name

drop table tb1;

The above is compiled and passed in the oralce 9i environment.

 

The above is found on the Internet, but the actual operation is that there are multiple columns, there are 0 cases, in fact, the SQL statement should be written in this way
select name name,
  max(case subject when 'language' then result else 0 end) language,
  max(case subject when 'math' then result else 0 end) math,
  max(case subject when 'physics' then result else 0 end) physics
from tb group by name;

The result is this:

Name Language Mathematics Physics
Zhang San 74 83 93
Li Si 74 84 94

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326372376&siteId=291194637