Oracle 中基于两个日期的排名[关闭]

Posted

技术标签:

【中文标题】Oracle 中基于两个日期的排名[关闭]【英文标题】:Ranking base on two dates in Oracle [closed] 【发布时间】:2013-06-01 11:50:11 【问题描述】:

我有一个查询结果如下:

我想我可以使用dense_rank 在一个时间间隔内对用户段进行分组。但它不起作用。

CUST_ID EVENT_ID SEGMENT_ID SEGMENT_CODE       DATE_FROM              DATE_TO
100      1424      21            A         2011.01.05. 13:03:12   2011.01.06. 23:40:13
100      1566      21            A         2011.01.06. 23:40:13   2011.02.28. 11:48:52
100      1580      21            A         2011.02.28. 11:48:52   2012.04.30. 2:49:53
100      1601      45            Y         2012.04.30. 2:49:53    2012.05.29. 21:12:27
100      1663      45            Y         2012.05.29. 21:12:27   2012.05.30. 11:11:23
100      1710      45            Y         2012.05.30. 11:11:23   2012.08.01. 5:14:36
100      1875      114           H         2012.08.01. 5:14:36    2012.09.01. 20:26:42
100      1880      33            F         2012.09.01. 20:26:42   2012.09.03. 9:12:23
100      1901      21            A         2012.09.03. 9:12:23    2012.09.03. 9:12:23
100      1903      21            A         2012.09.03. 9:12:23    2012.10.25. 17:25:14
100      1966      223           R         2012.10.25. 17:25:14   2013.01.01. 1:12:55
100      2011      223           R         2013.01.01. 1:12:55    3500:12:31. 23:59:59

我想要这样的东西:

CUST_ID EVENT_ID SEGMENT_ID SEGMENT_CODE       DATE_FROM              DATE_TO           DENSE_RANK
100      1424      21            A         2011.01.05. 13:03:12   2011.01.06. 23:40:13       1
100      1566      21            A         2011.01.06. 23:40:13   2011.02.28. 11:48:52       1
100      1580      21            A         2011.02.28. 11:48:52   2012.04.30. 2:49:53        1
100      1601      45            Y         2012.04.30. 2:49:53    2012.05.29. 21:12:27       2
100      1663      45            Y         2012.05.29. 21:12:27   2012.05.30. 11:11:23       2
100      1710      45            Y         2012.05.30. 11:11:23   2012.08.01. 5:14:36        2
100      1875      114           H         2012.08.01. 5:14:36    2012.09.01. 20:26:42       3
100      1880      33            F         2012.09.01. 20:26:42   2012.09.03. 9:12:23        4
100      1901      21            A         2012.09.03. 9:12:23    2012.09.03. 9:12:23        5
100      1903      21            A         2012.09.03. 9:12:23    2012.10.25. 17:25:14       5
100      1966      223           R         2012.10.25. 17:25:14   2013.01.01. 1:12:55        6
100      2011      223           R         2013.01.01. 1:12:55    3500:12:31. 23:59:59       6

你知道我该如何解决这个问题吗?

【问题讨论】:

到目前为止您尝试过哪些查询?像DENSE_RANK() OVER (PARTITION BY SEGMENT_ID ORDER BY DATE_FROM) "dense_rank" 这样的东西? “一段时间内的用户细分”尚不清楚您的意图...... “不起作用”是什么意思?您的查询是什么样的?它出什么问题了?你有错误吗?数据不正确?你的输出背后的逻辑是什么?为什么你的输出和你的输入一样? 无法正确解释。但是我会尝试。该查询显示一个客户群的生命周期。 如果一个片段只出现一次就很容易了。但如果这不是真的,整个情况就会改变。与段 A 一样。如果我使用 row_number 或 dense_rank 并按 cust_id 分区,segment_id 顺序按 valid_to、valid_from。使用 segment_id 21 对每一行进行排序,无论 21 段在生命周期中出现两个不同的时间 我的输出背后的逻辑是我想在一个段期间获得第一个 valid_from 和最后一个 valid_to。我的意思是 cust_id 100 从 2011.01.05 开始在 A 段中。 13:03:12 至 2012.04.30。 2:49:53。这是第一个间隔。但它从 2012.09.03 开始​​第二次出现在 A 段。 9:12:23 至 2012.10.25。 17:25:14。 【参考方案1】:

根据您的逻辑,dense_rank 不会。但是,您可以使用 lag() 和累积总和获得类似的效果。滞后查看段 id/段代码的先前日期值,如果它们重叠,则记录不是分组的开始。否则就是这样。

“isstarts”的累积总和就是你要找的:

select t.*,
       sum(case when date_from - prev_date_to < 0.00001
                then 0
                else 1
           end) over (partition by segment_id order by SEGMENT_ID, SEGMENT_CODE
                     ) as YourRanking
from (select t.*,
             lag(date_to) over (partition by SEGMENT_ID, SEGMENT_CODE
                                order by date_from
                               ) as prev_date_to
      from t
     ) t

因为这是日期/时间,所以查询不使用完全相等。相反,它会寻找一个小的差异。

【讨论】:

抱歉重播太晚了。这是个好主意。我可以使用它并解决问题!

以上是关于Oracle 中基于两个日期的排名[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL 排名查询

基于日期顺序的排名

oracle把查两个日期相减的天数变成数字类型

oracle中两个日期如何拼接成一个

获取Oracle中两个日期之间的天数,包括日期

如何在Oracle中生成一周的第一天,一周的最后一天和两个日期之间的周数