示例:
SELECT *
FROM [User]
WHERE [Value1] > 0
AND [Value2] / [Value1] > 3
我想避免一个被零除的情况。我可以确定首先检查第一个条件,如果第一个条件为假,第二个条件永远不会被击中吗?我想如果查询规划器能够产生更高的性能,则允许它重新排列序列。
答案 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
上的不是。