Oracle SQL中如何避免同Desc值的重复ID返回问题
Oracle SQL同Desc多版本行的最优筛选方案
针对你遇到的同Desc值但其他列(如Color)不同的行(示例中ID_04和ID_05),以下是几种最优解决方案,对应不同业务需求:
需求1:每个Desc只保留最新生效的行
如果需要每个Desc仅保留时间范围最晚生效的行,使用窗口函数ROW_NUMBER()分组排序,一次扫描即可完成,性能最优:
WITH ranked_data AS ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY "Desc" ORDER BY TO_DATE(ToDate, 'MM.YYYY') DESC ) AS rank_num FROM your_table ) SELECT ID, "Desc", FromDate, ToDate, Color FROM ranked_data WHERE rank_num = 1;
执行后会返回ID_05(D对应的最新行),若Desc列存在索引,该查询的执行效率会大幅提升。
需求2:筛选覆盖指定时间点的行
如果需要根据特定时间点,找到该时间点生效的Desc对应行,直接添加时间范围条件,配合复合索引(Desc+FromDate+ToDate)性能最佳:
SELECT ID, "Desc", FromDate, ToDate, Color FROM your_table WHERE "Desc" = 'D' AND TO_DATE(FromDate, 'MM.YYYY') <= TO_DATE('01.2020', 'MM.YYYY') AND TO_DATE(ToDate, 'MM.YYYY') >= TO_DATE('01.2020', 'MM.YYYY');
此查询会精准返回2020年1月生效的D对应行(ID_05)。
需求3:保留同Desc下Color变化的分段行
如果需要保留Desc相同但Color不同的所有分段行(即展示每个Color对应的时间区间),使用LAG()函数判断颜色变化:
WITH color_segment AS ( SELECT *, LAG(Color) OVER ( PARTITION BY "Desc" ORDER BY TO_DATE(FromDate, 'MM.YYYY') ) AS prev_color FROM your_table ) SELECT ID, "Desc", FromDate, ToDate, Color FROM color_segment WHERE prev_color IS NULL OR prev_color != Color;
执行后会返回ID_04和ID_05,因为它们的Color不同,属于两个独立的分段。
内容的提问来源于stack exchange,提问作者Danias1927
相关产品推荐
相关产品推荐

