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 中基于两个日期的排名[关闭]的主要内容,如果未能解决你的问题,请参考以下文章