这是我的输入数据:
MEMBER_ID EVENT AMT_SBSDY PLAN_ID EFF_DT TERM_DT
314450 SBSDY 0 NULL 01-SEP-2017 31-DEC-2017
314450 SBSDY 0 NULL 01-JAN-2018 30-JUN-2018
314450 SBSDY 40 NULL 01-JUL-2018 31-DEC-9999
314450 PLN 0 032 01-JAN-2018 31-DEC-9999
这是预期的输出:
MEMBER_ID EVENT_SBSDY EVENT_PLAN AMT_SBSDY PLAN_ID EFF_DT TERM_DT
314450 SBSDY NULL 0 NULL 01-SEP-2017 31-DEC-2017
314450 SBSDY PLN 0 032 01-JAN-2018 30-JUN-2018
314450 SBSDY PLN 40 032 01-JUL-2018 31-DEC-9999
成员是拥有两种不同事件(SBSDY-补贴金额和PLN-她的计划ID)的实体。
在第一个数据集中,该成员拥有第一个SBSDY事件,有效期从01-SEP-17到31-DEC-2017,补贴金额为$ 0。该成员有第二笔补贴事件,有效期从2018年01月01日至2018年6月30日(同样为$ 0),以及第三笔补贴事件,有效期为$ 40,有效日期为2018年01月01日至开放结束(当前有效)。
该成员还有一个PLN事件,从2018年1月01日至开放结束日期(当前有效)。该活动的日期范围与第二,第三次SUBSDY活动的日期范围重叠,因此从2018年1月1日到2018年6月1日,该会员的补贴金额为$ 0和计划ID 032,从2018年7月01日开始,该会员具有补贴金额为40美元,计划ID为032。
我需要在同一行而不是在不同的行中显示此详细信息(如源数据集中一样)。在日期范围为01-SEP-2017到2017年12月31日的输出数据集中,补贴金额为$ 0,并且Plan ID和Event_Plan为NULL(第一行)。对于2018年1月1日至2018年6月30日的日期范围,活动补贴= SBSDY(成员具有补贴金额),活动计划= PLN(成员具有该日期范围内的计划),计划ID为032,补贴= 0.输出数据集中的第三行显示了日期范围,从2018年7月01日到迄今为止,此行中的补贴金额为$ 40,计划ID为032。
我认为我需要做PIVOT,但是在这种情况下我仍然不清楚如何实现。
我的数据库是Oracle 12c第1版。
能帮我吗?
答案 0 :(得分:1)
目前尚不清楚补贴日期和计划日期是否始终如您所显示的那样对齐,但是假设它们可以,您可以使用keep dense_rank
获取最新的计划数据:
select member_id,
event,
max(case when event = 'PLN' then event end)
over (partition by member_id order by eff_dt) as event_plan,
amt_sbsdy,
max(case when event = 'PLN' then plan_id end)
over (partition by member_id order by eff_dt) as plan_id,
eff_dt,
term_dt
from your_table
,然后进行过滤以仅查看补贴事件:
-- CTE for your sample data
with your_table (member_id, event, amt_sbsdy, plan_id, eff_dt, term_dt) as (
select 314450, 'SBSDY', 0, NULL, date '2017-09-01', date '2017-12-31' from dual
union all select 314450, 'SBSDY', 0, NULL, date '2018-01-01', date '2018-06-30' from dual
union all select 314450, 'SBSDY', 40, NULL, date '2018-01-07', date '2099-12-31' from dual
union all select 314450, 'PLN', 0, '032', date '2018-01-01', date '2099-12-31' from dual
)
-- actual query
select member_id,
event as event_sbsdy,
event_plan,
amt_sbsdy,
plan_id,
eff_dt,
term_dt
from (
select member_id,
event,
max(case when event = 'PLN' then event end)
over (partition by member_id order by eff_dt) as event_plan,
amt_sbsdy,
max(case when event = 'PLN' then plan_id end)
over (partition by member_id order by eff_dt) as plan_id,
eff_dt,
term_dt
from your_table
)
where event = 'SBSDY'
order by member_id, eff_dt;
MEMBER_ID EVENT_SBSDY EVENT_PLAN AMT_SBSDY PLAN_ID EFF_DT TERM_DT
---------- ----------- ---------- ---------- ------- ---------- ----------
314450 SBSDY 0 2017-09-01 2017-12-31
314450 SBSDY PLN 0 032 2018-01-01 2018-06-30
314450 SBSDY PLN 40 032 2018-01-07 2099-12-31