为什么在 MS Sql 服务器的 Where 子句中使用 CASE 语句

Why CASE statement in Where clause for MS Sql server

在 MS SQL Server 2012 中对第 3 方供应商系统进行一些性能调整。

他们做了很多像这样的 where 子句:

WHERE 
(
   CASE
       WHEN  @searchID = '' THEN 1
       WHEN ((C.SAPCustomerNumber = @searchID ) OR (C.SAPCustomerNumber = @SapID)) THEN 1
    ELSE 0
    END = 1
                )

除了混淆查询计划之外,where 子句中的 Case 1 或 0 有什么好处?

谢谢

到目前为止,出现此类代码的最常见原因是有人不熟悉 SQL、CASE 表达式或两者。他们不知何故开始关注 CASE 并决定它应该用于所有条件评估。

这通常是一个错误,可以用更简单的布尔逻辑替换,正如@Bogdan 在评论中建议的那样:

((C.SAPCustomerNumber = @searchID ) OR (C.SAPCustomerNumber = @SapID) OR (@searchID = '' ))

可以这样做的第二个原因是如果有人试图强制执行谓词的评估顺序1CASE 被记录为按顺序评估其 WHEN 条件(前提是它们是标量表达式,而不是聚合)。不过,我真的不建议任何人实际编写这样的代码——它很容易被误认为是第一种形式。即使特定的评估顺序在今天是最好的,根据今天的数据,谁又能说它明天、一个月或几年后是否仍然正确?


1SQL 一般不保证 WHERE 子句谓词的任何求值顺序,也不保证任何形式的短路求值。优化器通常可以自由地重新排序谓词 - 在 WHERE 子句和 JOIN/ON 子句中 - 以尽可能便宜地获得整体结果。通常,您不应该试图阻止它这样做。

如果它没有选择最有效的计划,那么通过 updating/creating 索引和统计信息或实际强制执行特定计划可以更好地解决这个问题,而不是使用 CASE.