Oracle 12c中业务含义相同的多行数据如何筛选单条记录
Oracle 12c 双向等价记录去重方案
核心逻辑:给所有业务含义一致的记录生成完全相同的分组标识,按组筛选仅保留1条记录即可,针对往返航线这类正反顺序等价的场景,用固定排序规则统一两端字段值即可实现同组归类。
具体实现步骤
- 构造统一分组键
针对航线类两端点顺序不影响业务含义的场景,用LEAST()取两个地点中字典序更小的值、GREATEST()取字典序更大的值,不管出发地目的地顺序正反,两个值的组合完全固定,自然把正反航线归为同一组。 - 分组取单条记录
用Oracle 12c原生支持的ROW_NUMBER()窗口函数,按上述分组键做分区,按业务需要的规则排序后,取每个分区的第一条即可。
参考SQL
假设存储航班信息的表名为FLIGHT_DETAILS,包含字段:航班号FLIGHT_NO、出发地SOURCE、目的地DESTINATION、票价FARE,查询语句如下:
SELECT FLIGHT_NO, SOURCE, DESTINATION, FARE FROM ( SELECT fd.*, ROW_NUMBER() OVER ( -- 按统一的航线对分组,正反航线会进入同一个分区 PARTITION BY LEAST(SOURCE, DESTINATION), GREATEST(SOURCE, DESTINATION) -- 排序规则可按需调整:比如选最低票价就写 ORDER BY FARE ASC,选最早航班就按航班号排序 ORDER BY FLIGHT_NO ) AS row_rank FROM FLIGHT_DETAILS fd ) WHERE row_rank = 1;
调整说明
- 如果需要固定保留出发地字典序更小的那条记录,可以把窗口函数的
ORDER BY子句替换为ORDER BY CASE WHEN SOURCE = LEAST(SOURCE, DESTINATION) THEN 0 ELSE 1 END,会优先保留正向排列的航线。 - 如果存在其他业务等价的判断规则,只需要调整
PARTITION BY后的分组字段逻辑,保证同业务含义的记录计算出的分区键完全一致即可。 - 不建议用普通
GROUP BY做硬聚合,会丢失原始行的完整字段信息,窗口函数方案可以保留需要的任意原始列。
内容的提问来源于stack exchange,提问作者SwapnaSubham Das
相关产品推荐
相关产品推荐

