IS DISTINCT FROM 在 SQL Server 2022 中仍不可用,执行会报错“Incorrect syntax near 'DISTINCT'”;需用 NOT (col1 = col2 OR (col1 IS NULL AND col2 IS NULL)) 替代。

SQL Server 2022 不支持 IS DISTINCT FROM
直接说结论:IS DISTINCT FROM 在 SQL Server 2022 中仍不可用。它不是标准 T-SQL 语法,SQL Server 官方文档和实际执行都确认该操作符未被实现。你写 WHERE col1 IS DISTINCT FROM col2 会报错:Incorrect syntax near 'DISTINCT'。
为什么有人以为它能用?
常见混淆来源有三个:
- PostgreSQL 和 Oracle(12c+)确实支持
IS [NOT] DISTINCT FROM,且语义清晰:把两个NULL视为相等; - SQL 标准(ISO/IEC 9075)已纳入该语法,部分开发者误以为主流数据库同步跟进;
- SQL Server 的
ISNULL()函数名带 “IS”,容易让人联想存在类似语义的比较操作符。
SQL Server 中替代 IS DISTINCT FROM 的写法
假设你想表达“col1 和 col2 值不同(包括一方为 NULL 另一方非 NULL 的情况)”,必须手动展开逻辑。常用且安全的写法是:
WHERE (col1 <> col2) OR (col1 IS NULL AND col2 IS NOT NULL) OR (col1 IS NOT NULL AND col2 IS NULL)
更简洁的等价写法(推荐):
WHERE NOT (col1 = col2 OR (col1 IS NULL AND col2 IS NULL))
这个结构明确覆盖三类情况:
-
col1 = col2且都不为NULL→ 返回TRUE,外层NOT后为FALSE; -
col1和col2都为NULL→col1 = col2是UNKNOWN,但(col1 IS NULL AND col2 IS NULL)为TRUE,整体括号内为TRUE,外层NOT后为FALSE; - 仅一方为
NULL或二者非空但不等 → 括号内为FALSE,外层NOT后为TRUE,命中条件。
别踩 ISNULL() 当作比较操作符的坑
ISNULL() 是函数,不是操作符,不能用于列间差异判断:
-
WHERE ISNULL(col1, '') ISNULL(col2, '')看似可行,但有风险:如果列类型是INT,ISNULL(col1, '')会强制隐式转换失败或截断; -
WHERE ISNULL(col1, 'x') ISNULL(col2, 'x')依赖占位符值,若真实数据中恰好含'x',逻辑就错了; - 性能上,函数包裹列会阻止索引 Seek,尤其在大表
WHERE条件中要警惕。
真正需要稳定、可读、可索引的列对比逻辑,还是回归上面那个 NOT (A = B OR (A IS NULL AND B IS NULL)) 模式——它不依赖类型、不引入额外值、且 SQL Server 查询优化器能较好识别其语义。

















