根据3个月的日期间隔重置ROW_NUMBER个计数

时间:2018-12-27 21:47:57

标签: sql sas teradata row-number

寻找解决方案,以解决在超过三个月的日期字段( clm_line_srvc_strt_dt )中出现间隔时如何重新开始ROW_NUMBER计数的问题。

当前将以下内容用于行计数:

,ROW_NUMBER() 
OVER(PARTITION BY c.src_sbscrbr_id
, c.src_mbr_sqnc_nbr
, cl.hlth_srvc_cd 
, df.serv_prov_id
ORDER BY c.src_sbscrbr_id
, c.src_mbr_sqnc_nbr
, cl.hlth_srvc_cd 
, df.serv_prov_id
, cl.clm_line_srvc_strt_dt) as rncnt

例如: 成员ID 011包含三个记录,其clm_line_srvc_strt_dt字段分别为2017年12月28日,2018年4月28日和2018年7月28日。

当前,这3行的行数为 1、2、3

由于2017年12月28日到2018年4月28日之间的间隔大于3个月,因此行计数应使用2018年4月28日的行重置为1。因此应该为 1、1、2 ,因为从2018年4月28日到2018年7月28日之间的间隔不超过3个月,所以第三行继续计数。

3 个答案:

答案 0 :(得分:2)

您可以在数据步骤中遵循“滞后变量”方法。我使用了示例数据:

data sample;
input Mem_Id clm_line_srvc_strt_dt date9.;
format clm_line_srvc_strt_dt date9.;
datalines;
1011 28Dec2017
1011 28Apr2018
1011 28Jul2018
1011 28Aug2018
2012 15Apr2017
2012 15Jul2017
2012 15Oct2017
;
run;

proc sort data=sample; by Mem_Id clm_line_srvc_strt_dt; run;

data sample1;
 set sample;
  by Mem_id clm_line_srvc_strt_dt;
  Retain RowCount 0;

  diff=intck('MONTH',lag(clm_line_srvc_strt_dt),clm_line_srvc_strt_dt);
  if first.Mem_id then RowCount=1;
  else if diff<=3 then rowcount=rowcount+1;
  drop diff;
run; 

proc print data=sample1; run;

答案 1 :(得分:1)

Teradata支持对窗口聚合的专有扩展,RESET WHEN,它添加了一种动态分区:

Row_Number() 
Over(PARTITION BY c.src_sbscrbr_id
                , c.src_mbr_sqnc_nbr
                , cl.hlth_srvc_cd 
                , df.serv_prov_id
     ORDER BY  cl.clm_line_srvc_strt_dt
     -- restart the row number when the previous date is more than 3 months ago
     RESET WHEN Min(clm_line_srvc_strt_dt)
                Over (PARTITION BY c.src_sbscrbr_id
                                 , c.src_mbr_sqnc_nbr
                                 , cl.hlth_srvc_cd 
                                 , df.serv_prov_id
                      ORDER BY cl.clm_line_srvc_strt_dt
                      ROWS BETWEEN 1 Preceding AND 1 Preceding) 
               < Add_Months(cl.clm_line_srvc_strt_dt, -3)) AS rncnt

基于Gordon回答中的错误消息,您的Teradata版本尚不支持LAG(必须为16.10+)。 MIN与:

                LAG(clm_line_srvc_strt_dt)
                Over (PARTITION BY c.src_sbscrbr_id
                                 , c.src_mbr_sqnc_nbr
                                 , cl.hlth_srvc_cd 
                                 , df.serv_prov_id
                      ORDER BY cl.clm_line_srvc_strt_dt)  

顺便说一句,无需对您在PARTITION中已经使用过的相同列进行排序(无论如何,在分区中它的值都是相同的)

答案 2 :(得分:0)

您将使用累积和和lag()来执行此操作。这个想法是:

sum(case when cl.clm_line_srvc_strt_dt < prev_clm_line_srvc_strt_dt + interval '3 month'
         then 0 else 1
    end) over (partition by c.src_sbscrbr_id, c.src_mbr_sqnc_nbr, cl.hlth_srvc_cd, df.serv_prov_id
               order by cl.clm_line_srvc_strt_dt
              ) as rncnt
from (select . . .,
             lag(cl.clm_line_srvc_strt_dt) over (partition by c.src_sbscrbr_id, c.src_mbr_sqnc_nbr, cl.hlth_srvc_cd, df.serv_prov_id) as prev_clm_line_srvc_strt_dt
      . . .
     ) . . .