2016-07-27 58 views
0
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进行排序(活动的系列)如何基于列

  1. 如果“商誉” EVENT_DATE如下“试用”产品EVENT_DATE 然后将其视为“试用”。如果是“金汇” EVENT_DATE如下则 “付费”产品EVENT_DATE将此视为“付费”,并调整 TERM_END_DATE(实施例用于远程理想的情况下当存在一个REG_ID特定PACKAGE_DESC 没有 取消或EXPIRATION event_type_cd)

  2. 如果有一个事件后,取消则忽略取消(11163显示出来:是这样的原因,因为在取消后没有新的 事件)

  3. 如果有多个亲善的 我们需要的线索以下在 周期内取最大值TERM_END_DATE ds分配为TERM_END_DATE(REG_ID 17215和GUIDANCE)。
  4. EXPIRATION RECORD应始终存在,其term_start_date 需要调整为Cycle第一个 记录的Term_start_date。
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

@ a_horse_with_no_name - >感谢编辑我的问题,以便更好地理解.. :) – beckham

+0

我编辑了我的问题,以便更好地理解。再次感谢您的帮助。 – beckham

+0

我想弄清楚最终结果的排序顺序。从你提供的表格看来,它似乎是'reg_id,package_desc,event_date',只不过'reg_id'没有在你的表格中排序好:它再次下降。此外,还有不明确的情况,如决赛桌中的最后两行。他们如何订购?它是基于最后两列吗?像:'re​​g_id,package_desc,event_date,term_start_date,term_end_date'? – trincot

回答

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_IDpackage_desc)。

中间查询使用该信息来消除:

  • “取消”的记录,除非他们自己的周期的最后记录;
  • 连续的“善意”记录,只剩下最后一个代替每个序列 - 这是最后一个是临时的,但在这个阶段仍然需要;

中间查询还重新读取循环中的下一个记录的产品类型,因为它可能现在已经由于改为消除记录。此外,它确定:

  • term_start_date循环中的第一个记录的;
  • term_end_date该周期中的下一个记录;
  • product_type以前的记录在循环中;

最后,外部查询使用该信息:

  • 设置PRODUCT_TYPE到以前的纪录(或“试用”如果没有以前的),如果它涉及'GOODWILL'记录;
  • term_start_date设置为循环中第一条记录的条件,如果它涉及“到期”记录;
  • term_end_date设置为周期中下一条记录的条目,前提是下一条记录涉及“商誉”记录。

结果中排除'GOODWILL'记录(在上面第一个项目符号更改之前),除非它们与其周期中的第一个记录相关或与'EXPIRATION'或'CANCELLATION'记录。

order by子句使用你的评论中提到,有一个额外的event_type_cd desc确保“的EVENT_TYPE_CD的取消或到期将始终遵循新认购或追加销售特定REG_ID,PACKAGE_DESC”的顺序。这是因为幸运的是'新订阅'和'UPSELL'都是按字母顺序排列,而不是'取消'和'到期日期',所以按降序顺序排序。

+0

嗨Trincot,它像一个魅力。它给了我期望的输出,因为我已经测试了3次reg_id。非常感谢。我再一次没有语言来感谢你的所有努力。 :) – beckham

+0

嗨Trincot,我想你不会打扰你,因为你帮了我很多,直到现在。我昨天又发布了一个问题,看起来好像有我的问题投票,所以没有回应。你能否看到我在我的问题中是否缺少某些东西,并在该情景中帮助我。 :) http://stackoverflow.com/questions/38627219/how-to-delete-the-records-based-upon-prev-and-next-rows-and-assign-the-date-base – beckham

+0

我将有一个看。有一件事StackOverflow中的人不喜欢的是当你提出一个问题时,并没有显示你尝试过的代码。你应该总是添加一个段落,如*“我用这个SQL试过了.....但它没有给我预期的结果,我做错了什么?”*这将导致更少的反对票。重要的是你要表明你已经付出了努力,而不是要求社区为你做这项工作:)但是我会首先用更好的措词和格式更新你的问题。那么你应该添加这样一个段落。 – trincot