技术问询:识别特定分段与筛选符合时间条件的项目资格数据
嘿,我来帮你搞定这两个数据分析问题,先从第二个带具体数据集的需求说起!
问题2:筛选特定日期范围且无过往项目资格的行
首先看你的数据集,需求是找出生效日期在2018年2月1日到4月30日之间,并且对应ID在该行生效前没有任何其他项目资格的记录。简单来说,就是要找那些ID的第一个项目恰好落在这个日期范围内的行。
可以用NOT EXISTS子句来实现这个逻辑,SQL代码如下:
SELECT t1.* FROM your_table t1 WHERE t1.DATE_EFF BETWEEN '2018-02-01' AND '2018-04-30' AND NOT EXISTS ( SELECT 1 FROM your_table t2 WHERE t2.ID = t1.ID AND t2.DATE_EFF < t1.DATE_EFF );
代码解释:
- 外层查询先筛选出所有生效日期在目标区间内的记录;
NOT EXISTS子句用来检查当前ID是否存在更早生效的项目,如果不存在(也就是这是该ID的第一个项目),就保留这条记录。
不过看你提供的数据集,所有ID都有更早的项目,所以这个查询的结果会是空集,但逻辑是完全符合需求的。
问题1:识别上一段结束后6个月以上启动的最新分段
要实现这个需求,我们需要先给每个ID的项目分段按生效日期排序,拿到上一段的结束日期,再判断时间间隔,最后筛选出最新的符合条件的分段。这里用窗口函数LAG()和ROW_NUMBER()来处理最方便:
WITH ranked_segments AS ( SELECT *, -- 获取当前ID的上一个分段的结束日期 LAG(DATE_END) OVER (PARTITION BY ID ORDER BY DATE_EFF) AS prev_segment_end, -- 给每个ID的分段按生效日期倒序排名,最新的分段排名为1 ROW_NUMBER() OVER (PARTITION BY ID ORDER BY DATE_EFF DESC) AS rn FROM your_table ) SELECT ID, PGM, DATE_EFF, DATE_END FROM ranked_segments WHERE rn = 1 -- 只保留每个ID的最新分段 AND DATEDIFF(MONTH, prev_segment_end, DATE_EFF) > 6; -- 间隔超过6个月
代码解释:
- CTE部分:用
LAG()函数为每个分段匹配上一个分段的结束日期,同时用ROW_NUMBER()标记每个ID的最新分段; - 主查询:筛选出每个ID的最新分段,并且该分段的生效日期比上一段的结束日期晚超过6个月的记录。
如果你的需求是找出所有满足间隔条件的分段(而不仅仅是最新的),可以去掉rn = 1的条件,同时加上prev_segment_end IS NOT NULL来排除没有上一段的第一个分段:
WITH segments_with_prev AS ( SELECT *, LAG(DATE_END) OVER (PARTITION BY ID ORDER BY DATE_EFF) AS prev_segment_end FROM your_table ) SELECT ID, PGM, DATE_EFF, DATE_END FROM segments_with_prev WHERE prev_segment_end IS NOT NULL AND DATEDIFF(MONTH, prev_segment_end, DATE_EFF) > 6;
内容的提问来源于stack exchange,提问作者Dave Jabbz




