我有下表。从周期到程序的联接是基于日期的。 有数以百万计的PGMID条目,因此我一直在考虑枢轴功能,但是我无法对PGMID进行硬编码。任何想法/帮助将不胜感激。 我确实有能力编辑数据库中的表。
表:周期
ID START_CYCLE END_CYCLE
4400 7/22/2018 8/3/2018
4400 8/4/2018 8/5/2018
4400 8/6/2018 8/6/2018
4400 8/7/2018 8/9/2018
4400 8/10/2018 9/6/2018
4400 9/7/2018 9/7/2018
4400 9/8/2018 9/9/2018
4400 9/10/2018 12/31/9999
表:程序
PGMID START_DT END_DT
101 8/4/2018 9/10/2018
102 9/8/2018 9/8/2018
103 9/10/2018 NULL
输出:
ID START_CYCLE END_CYCLE PGMID
4400 7/22/2018 8/3/2018
4400 8/4/2018 8/5/2018 101
4400 8/6/2018 8/6/2018 101
4400 8/7/2018 8/9/2018 101
4400 8/10/2018 9/6/2018 101
4400 9/7/2018 9/7/2018 101
4400 9/8/2018 9/9/2018 101
4400 9/8/2018 9/9/2018 102
4400 9/10/2018 12/31/9999 103
有重复的周期条目,我不想重复任何日期。
4400 9/8/2018 9/9/2018 101
4400 9/8/2018 9/9/2018 102
预期输出:
ID START_CYCLE END_CYCLE PROGRAM1 PROGRAM2
4400 7/22/2018 8/3/2018
4400 8/4/2018 8/5/2018 101
4400 8/6/2018 8/6/2018 101
4400 8/7/2018 8/9/2018 101
4400 8/10/2018 9/6/2018 101
4400 9/7/2018 9/7/2018 101
4400 9/8/2018 9/9/2018 101 102
4400 9/10/2018 12/31/9999 103
答案 0 :(得分:3)
select *
from (
select id, start_cycle, end_cycle, pgmid, case when rn > 5 then 0 else rn end rn
from (
select id, start_cycle, end_cycle, pgmid,
row_number() over (partition by id, start_cycle, end_cycle order by pgmid) rn
from cycle c
left join program p on p.start_dt <= c.end_cycle and c.start_cycle <= p.end_dt ))
pivot (listagg(pgmid, ',') within group (order by pgmid)
for rn in (1 program1, 2 program2, 3 program3, 4 program4, 5 program5, 0 others))
order by id, start_cycle
pgmid
排序的row_number(),0
,others
min
或max
中使用listagg
如果每个循环中有超过5个程序,则需要这些步骤来显示所有程序。其余的都在others
中。如果您知道最多只能有3个程序,则可以简化此查询。
如果您希望每个程序在不同的列中并且最大列数未知,那么它就是动态枢轴问题。在堆栈溢出中已经描述了一些解决方案,但是这些大多数都是解决方法。
在此示例中,一个循环中最多有8个程序:
with
cycle(id, start_cycle, end_cycle) as (
select 4400, date '2018-07-22', date '2018-08-03' from dual union all
select 4400, date '2018-08-04', date '2018-08-05' from dual union all
select 4400, date '2018-08-06', date '2018-08-06' from dual union all
select 4400, date '2018-08-07', date '2018-08-09' from dual union all
select 4400, date '2018-08-10', date '2018-09-06' from dual union all
select 4400, date '2018-09-07', date '2018-09-07' from dual union all
select 4400, date '2018-09-08', date '2018-09-09' from dual union all
select 4400, date '2018-09-10', date '9999-12-31' from dual ),
program(pgmid, start_dt, end_dt) as (
select 101, date '2018-08-04', date '2018-09-10' from dual union all
select 104, date '2018-08-06', date '2018-08-07' from dual union all
select 105, date '2018-08-06', date '2018-08-07' from dual union all
select 106, date '2018-08-06', date '2018-08-07' from dual union all
select 107, date '2018-08-06', date '2018-08-07' from dual union all
select 108, date '2018-08-06', date '2018-08-07' from dual union all
select 109, date '2018-08-06', date '2018-08-07' from dual union all
select 110, date '2018-08-07', date '2018-08-07' from dual union all
select 102, date '2018-09-08', date '2018-09-08' from dual union all
select 103, date '2018-09-10', null from dual )
select *
from (
select id, start_cycle, end_cycle, pgmid, case when rn > 5 then 0 else rn end rn
from (
select id, start_cycle, end_cycle, pgmid,
row_number() over (partition by id, start_cycle, end_cycle order by pgmid) rn
from cycle c
left join program p on p.start_dt <= c.end_cycle and c.start_cycle <= p.end_dt ))
pivot (listagg(pgmid, ',') within group (order by pgmid)
for rn in (1 program1, 2 program2, 3 program3, 4 program4, 5 program5, 0 others))
order by id, start_cycle
结果:
ID START_CYCLE END_CYCLE PROGRAM1 PROGRAM2 PROGRAM3 PROGRAM4 PROGRAM5 OTHERS
----- ----------- ----------- --------- --------- --------- --------- --------- ------------
4400 2018-07-22 2018-08-03
4400 2018-08-04 2018-08-05 101
4400 2018-08-06 2018-08-06 101 104 105 106 107 108,109
4400 2018-08-07 2018-08-09 101 104 105 106 107 108,109,110
4400 2018-08-10 2018-09-06 101
4400 2018-09-07 2018-09-07 101
4400 2018-09-08 2018-09-09 101 102
4400 2018-09-10 9999-12-31 101
答案 1 :(得分:0)
1-您必须添加“按START_CYCLE,END_CYCLE分组” 2-在选择部分中必须添加group_concat(PGMID分隔符',')
我不了解oracle,但在mysql中是:
select ..., group_concat(PGMID separator ',') as PGMIDs, ...
from ...
join ...
where ...
group by START_CYCLE, END_CYCLE
希望对您有所帮助。