我正在努力替换当前使用PL / SQL游标迭代非常大的表的更新过程,使用展平数据更新多个列。
查询的结构使得展平结果只能通过限制为term和id返回单行。 term_eff列指示活动应何时开始出现在结果中,但结束日期没有当前限制。如何为test_person表中的所有行返回test_activity表的展平结果?
测试用例表:
create table test_person (id number,term varchar2(6));
create table test_activity(id number,term_eff varchar2(6),activity varchar2(10));
insert into test_person values(1,'201001');
insert into test_person values(1,'201101');
insert into test_person values(1,'201102');
insert into test_person values(2,'201001');
insert into test_person values(2,'201101');
insert into test_person values(2,'201102');
insert into test_activity values (1,'201001','Jump');
insert into test_activity values (1,'201001','Play');
insert into test_activity values (1,'201102','Run');
insert into test_activity values (2,'201001','Jump');
insert into test_activity values (2,'201101','Play');
insert into test_activity values (2,'201101','Run');
commit;
这是返回单行的当前查询。想要一个可以返回test_person表中所有行的值的版本。
select Max(CASE WHEN A.activity_rank = 1 THEN A.activity ELSE NULL END) AS activity1,
Max(CASE WHEN A.activity_rank = 2 THEN A.activity ELSE NULL END) AS activity2,
Max(CASE WHEN A.activity_rank = 3 THEN A.activity ELSE NULL END) AS activity3
from (SELECT id,
term_eff,
activity,
row_number() OVER (PARTITION BY ID ORDER BY term_eff desc) AS activity_rank
FROM test_activity
WHERE id = 1
AND term_eff <= '201001') A;
编辑:最终查询的预期结果:
ID Term Activity1 Activity2 Activity3
1 201001 Jump Play
1 201101 Jump Play
1 201102 Jump Play Run
...
答案 0 :(得分:0)
基本上,只需删除where
条件并添加group by
即可。你已经完成了艰难的任务:
select id,
Max(CASE WHEN A.activity_rank = 1 THEN A.activity ELSE NULL END) AS activity1,
Max(CASE WHEN A.activity_rank = 2 THEN A.activity ELSE NULL END) AS activity2,
Max(CASE WHEN A.activity_rank = 3 THEN A.activity ELSE NULL END) AS activity3
from (SELECT id, term_eff, activity,
row_number() OVER (PARTITION BY ID ORDER BY term_eff desc) AS activity_rank
FROM test_activity
WHERE term_eff <= '201001'
) A
group by id;