WHERE子句日期筛选异常:2020年正常2019年报错原因排查
问题分析与解决方案
看起来核心问题出在CTE的递归分支语法错误,而且这个错误只在处理2019年数据时才会触发,具体原因和解决方法如下:
为什么2020年可行,2019年不行?
你粘贴的CTE代码里,UNION ALL后的递归SELECT语句存在明显的语法问题——错误地把STUFF函数的结果当成了CHARINDEX的第三个参数(CHARINDEX的第三个参数是整数类型的起始位置,但STUFF返回的是字符串)。
而执行差异的原因是:
- 当筛选2020年数据时,所有匹配的
cases行的ClaimCategories列都没有换行符,CTE的递归分支根本不会执行(因为aa.ClaimCategoriesMulti会是空字符串,不满足WHERE aa.ClaimCategoriesMulti > ''的条件),所以语法错误没被触发,查询能正常跑。 - 当筛选2019年数据时,存在部分行的
ClaimCategories列包含换行符,导致递归分支被执行,此时语法错误暴露,触发了字符串转数值的转换错误——可能SQL Server的错误提示显示成了date/time转换(或者你可能看错了错误类型)。
修复步骤
1. 修正CTE的递归语法
把递归分支的SELECT语句改成正确的格式,确保LEFT和STUFF函数的参数完整且正确:
WITH aa (MatterNumber, claim_cat_NJS, ClaimCategoriesMulti) AS ( SELECT MatterNumber , LEFT(ic.ClaimCategories, CHARINDEX(CHAR(10), ic.ClaimCategories + CHAR(10)) - 1) , STUFF(ic.ClaimCategories, 1, CHARINDEX(CHAR(10), ic.ClaimCategories + CHAR(10)), '') FROM cases AS ic UNION ALL SELECT aa.MatterNumber , LEFT(aa.ClaimCategoriesMulti, CHARINDEX(CHAR(10), aa.ClaimCategoriesMulti + CHAR(10)) - 1) , STUFF(aa.ClaimCategoriesMulti, 1, CHARINDEX(CHAR(10), aa.ClaimCategoriesMulti + CHAR(10)), '') FROM aa WHERE aa.ClaimCategoriesMulti > '' )
2. 使用无歧义的日期格式
即使MatterOpenDate是date类型,也建议用SQL Server唯一不会歧义的日期格式yyyyMMdd来写筛选条件,避免任何隐式转换问题:
WHERE 1 = 1 AND c.MatterOpenDate > '20190101'
额外排查点
如果修正语法后仍然报错,那需要检查2019年数据中ClaimCategories列的内容,是否存在包含非预期特殊字符的行,导致CHARINDEX/LEFT/STUFF生成的字符串在后续操作中被误触发隐式日期转换。
内容的提问来源于stack exchange,提问作者Ciara
相关产品推荐
相关产品推荐

