如何解决LEAD/LAG分析函数在有序集合存在重复值时的平局问题?
问题分析与解决方案
首先,咱们先搞清楚为什么原SQL会得到这样的结果:
你的原语句LEAD(START_DATE) OVER (ORDER BY START_DATE)是对所有行按START_DATE排序后,逐行取下一行的START_DATE值。因为两条记录的START_DATE完全相同,排序后它们是连续的两行,所以第一条记录取到了第二条的日期(2018-03-22),而第二条记录没有下一行,所以返回NULL,这就出现了结果不一致的情况。
根据你的期望——要么两条记录的LEAD_START_DATE全为NULL,要么全为相同值——下面给出对应的解决方案:
方案:让同一日期的所有记录共享相同的LEAD值
这个方案可以同时满足你的两个期望:如果当前日期是数据集中的最后一个日期,所有同日期记录的LEAD_START_DATE都会是NULL;如果后面有其他日期,所有同日期记录都会拿到相同的下一个日期值。
实现思路是:先对START_DATE去重,获取每个唯一日期的LEAD值,再将原表与这个结果关联,让同一日期的所有记录复用同一个LEAD值。
最终SQL语句
WITH date_leads AS ( SELECT START_DATE, LEAD(START_DATE) OVER (ORDER BY START_DATE) AS LEAD_START_DATE FROM (SELECT DISTINCT START_DATE FROM TABLE) unique_dates ) SELECT T.VERSION_ID, T.START_DATE, dl.LEAD_START_DATE FROM TABLE T JOIN date_leads dl ON T.START_DATE = dl.START_DATE ORDER BY T.START_DATE, T.VERSION_ID;
验证你的示例数据
用你的测试数据执行上面的SQL,date_leads子查询会返回:
START_DATE | LEAD_START_DATE 2018-03-22 | NULL
关联原表后,最终结果就是:
VERSION_ID | START_DATE | LEAD_START_DATE Vrandom1 | 2018-03-22 | NULL Vrandom2 | 2018-03-22 | NULL
完全符合你“均为NULL”的期望。
如果你的数据中有多个不同日期(比如新增一条Vrandom3 2018-03-23),执行该SQL会得到:
VERSION_ID | START_DATE | LEAD_START_DATE Vrandom1 | 2018-03-22 | 2018-03-23 Vrandom2 | 2018-03-22 | 2018-03-23 Vrandom3 | 2018-03-23 | NULL
这就实现了“同一日期的记录LEAD值均相同”的需求。
内容的提问来源于stack exchange,提问作者Sourabh
相关产品推荐
相关产品推荐

