SQL Server中Collation影响日期字符串比较结果的疑问
本质原因
SQL Server的字符串比较不是默认按ASCII值对比,而是遵循当前生效的排序规则定义的字符优先级。不同排序规则会给字符分配不同的“权重”,比较时按权重大小判断,这和MySQL、SQLite默认的二进制(ASCII)比较逻辑完全不同。
你的案例拆解
默认排序规则下的结果
你执行SELECT CASE WHEN '2025/3/25' < '2025-03-18' THEN 'Y' ELSE 'N' END返回Y,是因为当前数据库用的排序规则(比如你测试的Latin1_General_CS_AI)中,-的排序权重比/低——换句话说,在这个规则的逻辑里,-被视为比/“更小”的字符。 这里的CS是区分大小写,AI`是忽略重音,但核心是字符的排序优先级由规则预先定义,和ASCII码没关系。二进制排序规则的差异
当你指定Latin1_General_BIN时,比较逻辑变成直接用字符的二进制编码(也就是ASCII值)对比。-的ASCII是45,/是47,所以'2025/3/25'的第三个字符/比'2025-03-18'的第三个字符-大,结果返回N,这和你预期的ASCII比较逻辑一致,也和MySQL、SQLite的默认行为对齐。MySQL/SQLite结果不同的原因
MySQL和SQLite默认采用基于字符二进制值的比较,和SQL Server的二进制排序规则逻辑一样,所以直接按ASCII码对比,自然返回N。
验证字符排序权重的方法
你可以直接测试单个字符在不同排序规则下的比较结果,确认权重差异:
-- 测试Latin1_General_CS_AI规则下'-'和'/'的比较 SELECT CASE WHEN '-' COLLATE Latin1_General_CS_AI < '/' THEN 'Y' ELSE 'N' END; -- 返回Y -- 测试二进制规则下的比较 SELECT CASE WHEN '-' COLLATE Latin1_General_BIN < '/' THEN 'Y' ELSE 'N' END; -- 返回Y(符合ASCII值45<47的逻辑)
解决建议
如果需要让SQL Server的字符串比较和ASCII值逻辑一致,显式指定二进制排序规则即可,比如:
SELECT CASE WHEN '2025/3/25' COLLATE Latin1_General_BIN < '2025-03-18' THEN 'Y' ELSE 'N' END;
内容的提问来源于stack exchange,提问作者user16648779

