满足条件时重新启动Row_Number序列

时间:2016-02-03 22:25:52

标签: sql oracle11g row-number dense-rank

我遇到了一个看似简单修复的障碍,但我似乎无法找到解决方案。我希望有些人在这里掌握更多Oracle SQL知识可以提供帮助。

基本上,我正在建立一个按完整日期排名的工作列表,这很简单。它们之间的共同联系是它们都是针对同一客户(不同的号码)和同一位置(不同的号码)。我的问题是,每当两个作业之间的持续时间超过30天时,我需要找到一种方法来中断并重新启动该等级/计数。以下是我正在查看的简化版本:

JOBCOUNT  ACCTNUM   LOCNUM      COMPDATE           DURATION  
--------  -------   ------      --------           -------- 
  2        001       003      8/21/2015 16:47     15.48763889        
  3        001       003      10/5/2015 11:31     41.98304398        
  4        001       003      10/19/2015 9:59     13.21804398        
  5        001       003      11/13/2015 15:23    24.43752315         
  6        001       003      11/30/2015 19:19    11.35537037        

由于第二行超过30的持续时间,我希望看到它如下:

JOBCOUNT  ACCTNUM   LOCNUM      COMPDATE           DURATION  
--------  -------   ------      --------           -------- 
  2        001       003      8/21/2015 16:47     15.48763889        
  1        001       003      10/5/2015 11:31     41.98304398        
  2        001       003      10/19/2015 9:59     13.21804398        
  3        001       003      11/13/2015 15:23    24.43752315         
  4        001       003      11/30/2015 19:19    11.35537037 

因为第二份工作不属于30天窗口,所以链条应该从下一个工作开始。我的问题是我找不到分区数据的方法,以便识别此条件并从计数开始。没有其他列允许我以这种方式对row_number或dense_rank进行分区(例如,每个30天链的常用订单键或系统作业序列)。

我已经尝试了大约20种不同的方法来解析我在这里读过的帖子中的数据无效,所以任何关于如何实现这些数据的帮助或想法都将以一种巨大的方式受到重视。我有大约50,000行数据需要应用这个序列。我现在已经在运行和工作中教了大约一年的SQL。我已经达到了我的知识限制。

1 个答案:

答案 0 :(得分:1)

基本上,您需要额外的分组。您可以通过对差异大于30计算的标记执行累计求和来计算分组。然后其余部分看起来像row_number()

select t.*,
       row_number() over (partition by acctnum, locnum, grp order by compdate) as jobcount  
from (select t.*,
             sum(case when duration > 30 then 1 else 0 end) over
                 (partition by acctnum, locnum order by compdate) as grp
      from t
     ) t;

但是,您的样本数据从2开始,而不是1,我不完全理解。