SELECT *
FROM [User]
WHERE [Value1] > 0
AND [Value2]/[Value1] > 3
我想避免一個部門被零的情況。我能確定首先檢查第一個條件,如果第一個條件是錯誤的,第二個條件不會被打到?我猜想如果查詢規劃器能夠產生更多的性能,就可以重新排列順序。
SELECT *
FROM [User]
WHERE [Value1] > 0
AND [Value2]/[Value1] > 3
我想避免一個部門被零的情況。我能確定首先檢查第一個條件,如果第一個條件是錯誤的,第二個條件不會被打到?我猜想如果查詢規劃器能夠產生更多的性能,就可以重新排列順序。
看來你正在尋找一個條件語句,IF。
http://msdn.microsoft.com/en-us/library/ms182717(SQL.90).aspx
一般沒有。優化器找出執行查詢的最佳方式。
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
爲什麼#2不安全? – User 2009-06-05 14:50:04
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
。無論如何,它幾乎都是免費的。
你最初的SQL代碼將很好地工作:)
那麼對於初學者...
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
您不能指望按所列順序處理您的條件的服務器。一般而言,優化程序將按照它認爲是更快的順序運行它們。通常情況下,你列出的應該是安全的,但我已經看到優化器感到困惑的邊緣情況。使優化的事情[Value1] > 0
條件會更快
一個很好的辦法就是對Value1
但上Value2
不的索引。
[Value1]/[Value1]> 3?我認爲你輸錯了,[Value1]/[Value1]幾乎總是1,除非你有0,在這種情況下,它將是未定義的。 – Joseph 2009-06-05 14:44:25
當然,打錯了,修好了,謝謝。 – User 2009-06-05 14:45:27