是否在WHERE子句中预定义了一系列条件检查?

时间:2009-06-05 14:38:02

标签: tsql

示例:

SELECT *
FROM [User]
WHERE [Value1] > 0
AND [Value2] / [Value1] > 3

我想避免一个被零除的情况。我可以确定首先检查第一个条件,如果第一个条件为假,第二个条件永远不会被击中吗?我想如果查询规划器能够产生更高的性能,则允许它重新排列序列。

6 个答案:

答案 0 :(得分:4)

SELECT  *
FROM    [User]
WHERE   CASE WHEN Value1 = 0 THEN 0 ELSE [Value2] / [Value1]  END > 3

,甚至更好:

SELECT  *
FROM    [User]
WHERE   [Value2] / NULLIF([Value1], 0) > 3

NULL分区始终是安全的。

请注意,如果您的表中有大量[Value1] = 0[Value1]上有索引,那么请查看以下内容:

SELECT  *
FROM    [User]
WHERE   [Value1] > 0
        AND [Value2] / NULLIF([Value1], 0) > 3

,将使用索引并跳过错误的值。

但是,不应该依赖它,并且仍然应该使用NULLIF。无论如何,它几乎是免费的。

答案 1 :(得分:0)

看来你正在寻找条件陈述,即IF http://msdn.microsoft.com/en-us/library/ms182717(SQL.90).aspx

答案 2 :(得分:0)

一般没有。优化器确定了执行查询的最佳方法。

SQL不会生成显式代码:它只是指向优化器返回某些格式,订单,过滤等数据的指令。

SELECT *
FROM [User]
WHERE [Value1] > 0
AND [Value1] / [Value1] > 3

--could be this
SELECT *
FROM
    (SELECT *
    FROM [User]
    WHERE [Value1] > 0
) foo
WHERE [Value1] / [Value1] > 3

--but to be safe
SELECT *
FROM
    (SELECT TOP 2000000000 *
    FROM [User]
    WHERE [Value1] > 0
    ORDER BY Value1
) foo
WHERE [Value1] / [Value1] > 3

答案 3 :(得分:0)

您的原始SQL代码将完美运行:)

答案 4 :(得分:0)

对于初学者来说......

Value1 / Value1 == 1 //always...

但假设它的列不同。

SELECT top 20 * from [User]
WHERE
CASE WHEN Value2 > 0
    THEN convert(decimal(18,2), Value1) / convert(decimal(18,2), Value2) 
    ELSE 0
END > 3 

答案 5 :(得分:0)

您不能指望服务器按列出的顺序处理您的条件。通常,优化器将以它认为更快的顺序运行它们。通常情况下,您列出的内容应该是安全的,但我看到优化程序混淆的边缘情况。

使[Value1] > 0条件更快的优化器的一个好方法是在Value1上建立一个索引,但Value2上的不是