SQL查询中AND使用是否异常?MSSQL无结果问题排查求助
这问题我之前踩过一模一样的坑!明明两个条件单独查都有数据,合起来用AND就没结果,大概率是日期格式解析歧义或者时间边界的隐藏坑在搞鬼,咱们一步步拆解排查:
1. 先确认日期字符串的解析是否正确
MSSQL对日期字符串的解析会依赖服务器的语言/区域设置,你用的'2018.04.23'这种点分隔格式,虽然看起来是yyyy.mm.dd,但偶尔会出现解析偏差(比如某些场景下被识别成yyyy.dd.mm)。
先跑个小查询验证解析结果:
SELECT CONVERT(datetime, '2018.04.23', 102) AS 解析后的开始日期, CONVERT(datetime, '2018.04.25', 102) AS 解析后的结束日期;
这里的102是MSSQL标准的yyyy.mm.dd格式代码,能强制服务器按你预期的格式解析日期。如果结果不是2018-04-23 00:00:00和2018-04-25 00:00:00,那就是日期格式的锅!
2. 时间边界的隐形陷阱
如果BATCHDT是datetime或datetime2类型(带时间部分),那BETWEEN '2018.04.23' AND '2018.04.25'其实只包含2018-04-25 00:00:00之前的记录。也就是说,那些SAMPLETYPEID='Environment'且BATCHDT在2018-04-25当天0点之后的记录,会被这个条件直接排除——而你单独查日期范围时看到的可能就是这些0点后的记录,但它们的SAMPLETYPEID并不符合?不对,你说单独查两个条件都有结果,那应该是有交集记录被时间边界漏掉了。
解决这个问题的两个安全姿势:
-- 方法1:补全结束时间,包含2018-04-25全天的所有记录 SELECT * FROM table1 WHERE SAMPLETYPEID = 'Environment' AND BATCHDT BETWEEN CONVERT(datetime, '2018.04.23', 102) AND CONVERT(datetime, '2018.04.25 23:59:59.997', 102); -- 方法2:用>=和<代替BETWEEN(更推荐,彻底避免时间边界问题) SELECT * FROM table1 WHERE SAMPLETYPEID = 'Environment' AND BATCHDT >= CONVERT(datetime, '2018.04.23', 102) AND BATCHDT < CONVERT(datetime, '2018.04.26', 102);
3. 验证是否真的存在重叠数据
最后可以跑个统计查询,确认有没有同时满足两个条件的记录:
SELECT COUNT(*) AS 符合双条件的记录数 FROM table1 WHERE SAMPLETYPEID = 'Environment' AND BATCHDT >= CONVERT(datetime, '2018.04.23', 102) AND BATCHDT < CONVERT(datetime, '2018.04.26', 102);
如果这个查询返回大于0的数,那之前的联合查询就是因为日期解析或时间边界的问题没查到;如果返回0,那说明确实没有同时满足两个条件的记录(虽然两边单独查都有数据,但没有交集)。
内容的提问来源于stack exchange,提问作者Jimin Choi

