?错误场景描述:现在在我的预约订单里面截止日期明明已经超过了当前时间却还显示,这个时候正常逻辑是只显示在历史订单中的。?
错误归因:关于下面这段查询中 这一组条件加上()与不加上括号天差地别,也是导致业务错误的原因。
解决办法: 标红的条件加上(),此时截止入场时间超过当前时间的预约订单就没有在预约订单出现了,而只出现在历史订单中(也就是过期订单)
SELECT ro.*, pa.location, pl.place_code, pl.floor, pa.lng AS parkingLng, pa.lat AS parkingLat?
FROM reserve_order ro LEFT JOIN parking pa?
ON ro.parking_id = pa.id LEFT JOIN place pl?
ON ro.place_id = pl.id?
WHERE ro.del_flag = '0'?
AND (ro.create_by = '13986915552'?OR ro.ordering_user = '13986915552'?)
AND ro.deadline >= NOW()?
ORDER BY ro.id DESC
?
?
?
不加上括号(造成业务错误的原因)使用下面这段sql查询,此时查出来 11 条数据
?
SELECT ro.*, pa.location, pl.place_code, pl.floor, pa.lng AS parkingLng, pa.lat AS parkingLat?
FROM reserve_order ro LEFT JOIN parking pa?
ON ro.parking_id = pa.id LEFT JOIN place pl?
ON ro.place_id = pl.id?
WHERE ro.del_flag = '0'?
AND ro.create_by = '13986915552'?OR ro.ordering_user = '13986915552'?AND ro.deadline >= NOW()?
ORDER BY ro.id DESC
?
可以看到返回了11条数据和我们数据库返回的记录数一样。
首先AND (ro.create_by = '13986915552'?OR ro.ordering_user = '13986915552'?)
是将 括号里面的条件作为一个整体 查询数据后,然后再根据条件AND ro.deadline >= NOW() 去过滤
而如果讲括号去掉 AND ro.create_by = '13986915552'?OR ro.ordering_user = '13986915552'? 这样作为两个条件过滤。虽然最后加了时间条件的过滤AND ro.deadline >= NOW()会把截止入场时间过期的给过滤掉,但是由于?OR ro.ordering_user = '13986915552'这个条件的加入又会把,满足该条件的过期的数据又给查出来最终导致了我们业务逻辑上的错误!
总结一点在使用了or条件的最好将相关的两个或多个条件单独用()括起来避免,or扩大了查询范围出错。而且这个问题比较隐蔽,不好排查。我也是尽量用例子加文字来更可能的表达清楚这个问题,如果大家觉得对你有帮助的话。多多点赞关注支持,我也会持续更新更多相关文章。又不足的地方还请大家多多指出探讨,让我们共同成长!!!
?