基于双主键与日期范围的Left Join丢失行问题排查与修正
SQL查询修正方案
问题根源
- WHERE子句过滤了左连接的空匹配:原查询将
B.LETTER_NAME IN ('A','B','C')放在WHERE中,左连接后A表无匹配的记录会返回B字段全为NULL,而NULL不满足IN条件,导致这部分记录被过滤,最终结果少于5000条。 - 未处理Table A的重复数据:Table A存在重复的Plan_Set_Up_Date,需要先确保每个Loan_Number仅返回一条唯一记录。
修正后的查询语句
-- 先对Table A去重,得到每个Loan_Number对应的唯一Plan_Set_Up_Date WITH Unique_A AS ( SELECT DISTINCT Loan_Number, Client_Number, Plan_Set_Up_Date AS PLAN_CREATE_DATE FROM A ) SELECT ua.PLAN_CREATE_DATE, ua.LOAN_NUMBER, ua.CLIENT_NUMBER, b.LETTER_NAME, b.LETTER_DATE FROM Unique_A ua LEFT JOIN B b ON ua.LOAN_NUMBER = b.LOAN_NUMBER AND ua.CLIENT_NUMBER = b.CLIENT_NUMBER AND b.LETTER_NAME IN ('A', 'B', 'C') -- 将函件类型过滤移至JOIN条件 AND b.LETTER_DATE BETWEEN ua.PLAN_CREATE_DATE AND (CAST(ua.PLAN_CREATE_DATE AS DATE) + INTERVAL '5' DAY)
关键修正说明
- 提前去重Table A:通过CTE
Unique_A提取Table A中每个Loan_Number的唯一记录,确保基础数据集为5000条。 - 调整过滤条件位置:把B表的函件类型、日期判断都放在LEFT JOIN的ON子句中,这样左连接时只会匹配符合条件的B表记录,无匹配的A表记录会完整保留,对应的B字段返回NULL。
- 移除冗余条件:原JOIN中的
B.LETTER_DATE IS NULL属于冗余逻辑,左连接本身会自动处理无匹配的情况,无需额外声明。
内容的提问来源于stack exchange,提问作者Junior Garcia
相关产品推荐
相关产品推荐

