SQL按type匹配不同日期字段过滤返回全量数据问题排查
问题产生原因
- 核心逻辑错误:使用
OR连接两个阈值判断属于逻辑冗余且错误。a <= '2022-06-08' OR a <= '2022-06-09'等价于a <= '2022-06-09',只要计算出的日期不晚于2022-06-09就会被返回。测试数据里最后一条Out类型记录trans_date为2022-06-09,刚好满足这个条件,因此被错误返回,最终出现全表数据都被查出的结果。 - 规则匹配逻辑错误:原SQL把不同交易类型的判断阈值放在CASE逻辑外,没有做到「不同类型对应不同判断字段+不同截止日期」的绑定,本质是把两个独立的过滤规则混在了一起。
- 大小写匹配隐患:测试数据中type字段值为首字母大写的
In/Out,原SQL判断条件写的是全大写'IN',在大小写敏感的数据库配置下会导致CASE判断失效,错误走到ELSE分支取trans_date字段计算。
正确SQL写法
推荐语义最清晰、最不容易出错的写法,直接按规则拆分条件:
SELECT * FROM tx WHERE (type = 'In' AND DATE(settle_date) <= '2022-06-09') OR (type = 'Out' AND DATE(trans_date) <= '2022-06-08');
如果偏好CASE写法,可将判断逻辑完全放入CASE语句中,避免外层条件写错:
SELECT * FROM tx WHERE CASE WHEN type = 'In' THEN DATE(settle_date) <= '2022-06-09' WHEN type = 'Out' THEN DATE(trans_date) <= '2022-06-08' ELSE FALSE END;
执行结果验证
基于提供的测试数据:
- 前2条In类型记录:settle_date为2022-06-09,满足In类型过滤规则,正常返回
- 第3条Out类型记录:trans_date为2022-06-08,满足Out类型过滤规则,正常返回
- 第4条Out类型记录:trans_date为2022-06-09,不满足Out类型需<=2022-06-08的规则,被正确过滤
内容的提问来源于stack exchange,提问作者Alvin
相关产品推荐
相关产品推荐

