oracle 动态行转列
场景:oracle动态行转列解决思路
oracle动态行转列
例:学生成绩表(tb)如下:
姓名 课程 分数
张三 语文 74
张三 数学 83
张三 物理 93
李四 语文 74
李四 数学 84
李四 物理 94
变成(得到如下结果):
姓名 语文 数学 物理
---- ---- ---- ----
李四 74 84 94
张三 74 83 93
-------------------
*/
create table tb(姓名 varchar(10) , 课程 varchar(10) , 分数 int)
insert into tb values('张三' , '语文' , 74)
insert into tb values('张三' , '数学' , 83)
insert into tb values('张三' , '物理' , 93)
insert into tb values('李四' , '语文' , 74)
insert into tb values('李四' , '数学' , 84)
insert into tb values('李四' , '物理' , 94)
静态写法
1、case when 写法
select 姓名,
max(case 课程 when '数学' then 分数 else 0 end 数学,
max(case 课程 when '语文' then 分数 else 0 end 语文,
max(case 课程 when '物理' then 分数 else 0 end 物理
from TB group by 姓名
2、decode写法
select 姓名,
max(decode (课程,'数学',分数,0)) 数学,
max(decode (课程,'语文',分数,0)) 语文,
max(decode (课程,'物理',分数,0)) 物理
from TB group by 姓名
动态写法
执行下面存储过程报值太多的错
declare
lv_sql varchar2(1000);
sql_command varchar2(5000);
cursor cur is select 课程 from TB group by 课程;
begin
sql_command := 'select 姓名';
for i in cur loop
-- decode 写法
sql_command := sql_command||' , max(decode(课程,'''||i.课程||''', 分数,0)) ' ||i.课程;
-- case when 写法
sql_command := sql_command||',max(case 课程 when '''||i.课程||''' then 分数 else 0 end ' || i.课程;
end loop;
sql_command := sql_command||' from TB group by 姓名';
lv_sql := 'insert into temp_ss ' || sql_command;
dbms_output.put_line(lv_sql);
execute immediate lv_sql;
end;
------解决方案--------------------
create or replace procedure tt as
lv_sql varchar2(1000);
sql_command varchar2(5000);
sql_create_table varchar2(5000);
cursor cur is select distinct(课程) from TB ;
begin
sql_command := 'select 姓名';
for i in cur loop
-- decode 写法
sql_command := sql_command
------解决方案--------------------
' , max(decode(课程,'''
------解决方案--------------------
i.课程
------解决方案--------------------
''', 分数,0)) '
------解决方案--------------------
i.课程;
end loop;
---首先删除临时表 temp_ss
--lv_sql :='drop table temp_ss ';
--execute immediate lv_sql;
---创建表
sql_create_table := 'create table temp_ss as '
------解决方案--------------------
sql_command
------解决方案--------------------
' from tb group by 姓名 ' ;
execute immediate sql_create_table;
end tt;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as SYS
SQL> select * from tb;
姓名 课程 分数
---------- ---------- ---------------------------------------
张三 语文 74
张三 数学 83
张三 物理 93
李四 语文 74
李四 数学 84
李四 物理 94
6 rows selected
SQL> select * from temp_ss;
姓名 数学 语文 物理
---------- ---------- ---------- ----------
李四 84 74 94
张三 83 74 93
SQL>
oracle动态行转列
例:学生成绩表(tb)如下:
姓名 课程 分数
张三 语文 74
张三 数学 83
张三 物理 93
李四 语文 74
李四 数学 84
李四 物理 94
变成(得到如下结果):
姓名 语文 数学 物理
---- ---- ---- ----
李四 74 84 94
张三 74 83 93
-------------------
*/
create table tb(姓名 varchar(10) , 课程 varchar(10) , 分数 int)
insert into tb values('张三' , '语文' , 74)
insert into tb values('张三' , '数学' , 83)
insert into tb values('张三' , '物理' , 93)
insert into tb values('李四' , '语文' , 74)
insert into tb values('李四' , '数学' , 84)
insert into tb values('李四' , '物理' , 94)
静态写法
1、case when 写法
select 姓名,
max(case 课程 when '数学' then 分数 else 0 end 数学,
max(case 课程 when '语文' then 分数 else 0 end 语文,
max(case 课程 when '物理' then 分数 else 0 end 物理
from TB group by 姓名
2、decode写法
select 姓名,
max(decode (课程,'数学',分数,0)) 数学,
max(decode (课程,'语文',分数,0)) 语文,
max(decode (课程,'物理',分数,0)) 物理
from TB group by 姓名
动态写法
执行下面存储过程报值太多的错
declare
lv_sql varchar2(1000);
sql_command varchar2(5000);
cursor cur is select 课程 from TB group by 课程;
begin
sql_command := 'select 姓名';
for i in cur loop
-- decode 写法
sql_command := sql_command||' , max(decode(课程,'''||i.课程||''', 分数,0)) ' ||i.课程;
-- case when 写法
sql_command := sql_command||',max(case 课程 when '''||i.课程||''' then 分数 else 0 end ' || i.课程;
end loop;
sql_command := sql_command||' from TB group by 姓名';
lv_sql := 'insert into temp_ss ' || sql_command;
dbms_output.put_line(lv_sql);
execute immediate lv_sql;
end;
Oracle
------解决方案--------------------
create or replace procedure tt as
lv_sql varchar2(1000);
sql_command varchar2(5000);
sql_create_table varchar2(5000);
cursor cur is select distinct(课程) from TB ;
begin
sql_command := 'select 姓名';
for i in cur loop
-- decode 写法
sql_command := sql_command
------解决方案--------------------
' , max(decode(课程,'''
------解决方案--------------------
i.课程
------解决方案--------------------
''', 分数,0)) '
------解决方案--------------------
i.课程;
end loop;
---首先删除临时表 temp_ss
--lv_sql :='drop table temp_ss ';
--execute immediate lv_sql;
---创建表
sql_create_table := 'create table temp_ss as '
------解决方案--------------------
sql_command
------解决方案--------------------
' from tb group by 姓名 ' ;
execute immediate sql_create_table;
end tt;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as SYS
SQL> select * from tb;
姓名 课程 分数
---------- ---------- ---------------------------------------
张三 语文 74
张三 数学 83
张三 物理 93
李四 语文 74
李四 数学 84
李四 物理 94
6 rows selected
SQL> select * from temp_ss;
姓名 数学 语文 物理
---------- ---------- ---------- ----------
李四 84 74 94
张三 83 74 93
SQL>