oracle交叉表,动态SQL

来源:百度知道 编辑:UC知道 时间:2024/05/29 10:13:38
例:oracle数据库
表名:test
具体数列:
ID name subject money
1 张三 项目A 40
2 李四 项目A 50
3 王五 项目A 60
4 张三 项目B 70
5 李四 项目B 80
6 王五 项目B 90

想要的结果
name 项目A 项目B
张三 40 70
李四 50 80
王五 60 90

我执行的代码是:
select name,
sum(CASE SUBJECT WHEN '项目A' THEN MONEY ELSE 0 END ) as 项目A,
sum(CASE SUBJECT WHEN '项目B' THEN MONEY ELSE 0 END ) as 项目B
FROM TSET
GROUP BY NAME

虽然这个例子中可以得到我想要的结果,但仔细一想,如果subject字段有800个项目,这种写法就不适用了,我又到网上查了下资料用另一种写法,但我没测试成功

CREATE OR REPLACE PACKAGE BODY "TEST1" as
procedure sp_test(p_cursor out t_cursor)
?? is
?? sqlstr varchar2(32767);
?? begin
?? sqlstr:='select name,';
?? for v_cur in (select distinct subject from test)
?? loop
?? sqlstr:=sqlstr||'sum(case subject when '''|| v_cur.subject ||

代码没有问题,只是你不会用工具
把下面内容存于C:\T.SQL,再在sql plus 命令行输入:@C:\T 即得到结果!

CREATE OR REPLACE PACKAGE TEST2
as
TYPE t_cursor IS REF CURSOR; --定义游标变量用于返回记录集

procedure sp_test(p_cursor out t_cursor) ;
end TEST2;
/
CREATE OR REPLACE PACKAGE BODY TEST2 as
procedure sp_test(p_cursor out t_cursor)
is
sqlstr varchar2(32767);
begin
sqlstr:='select name,';
for v_cur in (select distinct subject from test)
loop
sqlstr:=sqlstr||'sum(case subject when '''|| v_cur.subject ||''' then money else 0 end ) as '|| v_cur.subject ||',';
end loop;
sqlstr := substr(sqlstr,0,length(sqlstr)-1) ||' from test group by name';
open p_cursor for sqlstr;
end;
end;
/
var c refcursor
exec TEST2.sp_test(:c)
print c;

-----把上面内容存于C:\T.SQL,再在sql plus 命令行输入:@C:\T