REG_ID| EVENT_TYPE_CD | EVENT_DATE | PACKAGE_DESC |PRODUCT_TYPE|TERM_START_DATE|TERM_END_DATE
------|------------------|------------|-----------------|------------|---------------|----------
11156 | NEW SUBSCRIPTION | 23-FEB-16 | CONNECTED CARE |PAID | 23-FEB-16 | 23-FEB-16
11156 | CANCELLATION | 23-FEB-16 | CONNECTED CARE |PAID | 23-FEB-16 | 23-FEB-16
11156 | UPSELL | 23-FEB-16 | CONNECTED CARE |GOODWILL | 23-FEB-16 | 22-MAR-16
11156 | CANCELLATION | 11-MAR-16 | CONNECTED CARE |GOODWILL | 23-FEB-16 | 11-MAR-16
11156 | UPSELL | 14-MAR-16 | CONNECTED CARE |GOODWILL | 14-APR-16 | 13-APR-17
11156 | EXPIRATION | 14-APR-16 | CONNECTED CARE |GOODWILL | 14-MAR-16 | 13-APR-17
11163 | UPSELL | 23-FEB-16 | CONNECTED CARE |PAID | 23-FEB-16 | 23-FEB-16
11163 | CANCELLATION | 23-FEB-16 | CONNECTED CARE |PAID | 23-FEB-16 | 22-MAR-16
17215 | NEW SUBSCRIPTION | 18-JAN-16 | CONNECTED CARE |TRIAL | 18-JAN-16 | 17-JAN-17
17215 | NEW SUBSCRIPTION | 18-JAN-16 | GUIDANCE |TRIAL | 18-JAN-16 | 17-APR-16
17215 | CANCELLATION | 22-FEB-16 | GUIDANCE |TRIAL | 18-JAN-16 | 22-FEB-16
17215 | UPSELL | 25-FEB-16 | GUIDANCE |GOODWILL | 25-FEB-16 | 24-APR-16
17215 | EXPIRATION | 25-APR-16 | GUIDANCE |GOODWILL | 25-FEB-16 | 24-APR-16
17215 | NEW SUBSCRIPTION | 18-JAN-16 | REMOTE |TRIAL | 18-JAN-16 | 17-APR-16
17215 | UPSELL | 25-FEB-16 | REMOTE |GOODWILL | 25-FEB-16 | 24-APR-16
17215 | NEW SUBSCRIPTION | 18-JUN-16 | REMOTE |PAID | 18-JUN-16 | 17-JUL-16
17215 | UPSELL | 25-JUL-16 | REMOTE |GOODWILL | 25-JUL-16 | 24-AUG-16
我需要的输出是所有东西都需要按EVENT_DATE(事件系列)排序
如果'商誉'EVENT_DATE在'试用'产品EVENT_DATE之后 然后将其视为“试用”。如果'商誉'EVENT_DATE跟随a '付费'产品EVENT_DATE然后将其视为'付费'并调整 TERM_END_DATE(REMOTE示例没有时的理想情况 特定PACKAGE_DESC的取消或EXPIRATION event_type_cd 在REG_ID)
如果在取消后有事件,则忽略取消(11163显示:这是因为没有新的 取消后的活动)
REG_ID| EVENT_TYPE_CD | EVENT_DATE | PACKAGE_DESC |PRODUCT_TYPE|TERM_START_DATE| TERM_END_DATE
------|------------------|------------|-----------------|------------|---------------|----------
11156 | NEW SUBSCRIPTION | 23-FEB-16 | CONNECTED CARE |PAID | 23-FEB-16 | 13-APR-17
11156 | EXPIRATION | 14-APR-16 | CONNECTED CARE |PAID | 23-FEB-16 | 13-APR-17
11163 | UPSELL | 23-FEB-16 | CONNECTED CARE |PAID | 23-FEB-16 | 23-FEB-16
11163 | CANCELLATION | 23-FEB-16 | CONNECTED CARE |PAID | 23-FEB-16 | 22-MAR-16
17215 | NEW SUBSCRIPTION | 18-JAN-16 | CONNECTED CARE |TRIAL | 18-JAN-16 | 17-JAN-17
17215 | NEW SUBSCRIPTION | 18-JAN-16 | GUIDANCE |TRIAL | 18-JAN-16 | 24-APR-16
17215 | EXPIRATION | 25-APR-16 | GUIDANCE |TRAIL | 18-JAN-16 | 24-APR-16
17215 | NEW SUBSCRIPTION | 18-JAN-16 | REMOTE |TRIAL | 18-JAN-16 | 24-APR-16
17215 | NEW SUBSCRIPTION | 18-JUN-16 | REMOTE |PAID | 18-JUN-16 | 24-AUG-16
答案 0 :(得分:2)
规则非常广泛,使用PL / SQL代码可能会获得更好的结果和性能,因为它可以在迭代游标时使用变量。
不过,我认为以下查询可能会满足您的需求:
select reg_id,
event_type_cd,
event_date,
package_desc,
case product_type when 'GOODWILL' then coalesce(prev_product_type, 'TRIAL')
else product_type
end as product_type,
case event_type_cd when 'EXPIRATION' then first_term_start_date
else term_start_date
end as term_start_date,
case next_product_type when 'GOODWILL' then next_term_end_date
else term_end_date
end as term_end_date
from (select reg_id,
event_type_cd,
event_date,
package_desc,
product_type,
term_start_date,
term_end_date,
first_value(term_start_date) over (
partition by reg_id, package_desc
order by event_date, term_end_date, event_type_cd desc) as first_term_start_date,
lead(term_end_date, 1) over (
partition by reg_id, package_desc
order by event_date, term_end_date, event_type_cd desc) as next_term_end_date,
lag(product_type, 1) over (
partition by reg_id, package_desc
order by event_date, term_end_date, event_type_cd desc) as prev_product_type,
lead(product_type, 1) over (
partition by reg_id, package_desc
order by event_date, term_end_date, event_type_cd desc) as next_product_type
from (select reg_id,
event_type_cd,
event_date,
package_desc,
product_type,
term_start_date,
term_end_date,
lead(product_type, 1, '-') over (
partition by reg_id, package_desc
order by event_date, term_end_date, event_type_cd desc) as next_product_type
from mytable)
where not (event_type_cd = 'CANCELLATION' and next_product_type <> '-')
and not (product_type = 'GOODWILL' and next_product_type = 'GOODWILL')
)
where not ( product_type = 'GOODWILL'
and event_type_cd not in ('EXPIRATION', 'CANCELLATION')
and prev_product_type is not null)
order by reg_id, package_desc, event_date, term_end_date, event_type_cd desc
查询具有两级嵌套子查询。
最内层查询仅用于获取周期内下一条记录的 product_type (即在 reg_id 的同一分区内和 package_desc )。
中间查询使用该信息消除:
中间查询还会重新获取周期中下一条记录的 product_type ,因为它现在可能因已删除的记录而发生更改。此外,它确定:
最后,外部查询使用此信息:
“GOODWILL”记录(在上面第一个项目中的更改之前)被排除在结果之外,除非它们与周期中的第一条记录相关,或者对应于“EXPIRATION”或“CANCELLATION”记录。 / p>
order by
子句使用您在评论中提到的顺序,并使用额外的event_type_cd desc
来确保“取消或过期的EVENT_TYPE_CD将始终遵循新订阅或UPSELL特别是REG_ID,PACKAGE_DESC“。这是因为幸运的是,“NEW SUBSCRIPTION”和“UPSELL”都是按字母顺序出现,而不是“取消”和“EXPIRATION”,所以按降序排列,我们将它们排序正确。