我很想有一個T-SQL語句像下面...CASE語句切換WHERE條件
SELECT [field]
FROM [table]
WHERE CASE @flag
WHEN 1 THEN col1 = @value
ELSE col2 = @different_value
END
問題的關鍵是我想提出一個標誌,在我的功能使用不同的where子句中相同的查詢。我只是無法讓它工作。這可能嗎?
我很想有一個T-SQL語句像下面...CASE語句切換WHERE條件
SELECT [field]
FROM [table]
WHERE CASE @flag
WHEN 1 THEN col1 = @value
ELSE col2 = @different_value
END
問題的關鍵是我想提出一個標誌,在我的功能使用不同的where子句中相同的查詢。我只是無法讓它工作。這可能嗎?
這是否適合您?
Where (@flag = 1 and col1 = @value) or (@flag != 1 and col2 = @different_value).
隨着mySQL的聲明應該工作,因爲mySQL支持二進制表達式。
所以你一定要試試這個
SELECT [field]
FROM [table]
WHERE CASE @flag
WHEN 1
THEN case when col1 = @value then 1 else 0 end
ELSE case when col2 = @different_value then 1 else 0 end
END = 1
這是不是很不錯的可讀性。請注意性能問題,因爲優化器可能在這裏掙扎。
優化器可能在這裏掙扎。使它工作並使其快速工作(使用索引)通常是完全不同的。 – 2010-07-15 14:57:33
基於給定參數的動態改變搜索是一個複雜的問題,並做了一個又一個的方式,即使只有極輕微的不同,可以有巨大的性能影響。關鍵是要使用索引,忽略緊湊的代碼,不要擔心重複的代碼,你必須制定一個好的查詢執行計劃(使用索引)。
閱讀並考慮所有的方法。你最好的方法將取決於您的參數,你的數據,你的模式,你的實際使用情況:
Dynamic Search Conditions in T-SQL by by Erland Sommarskog
The Curse and Blessings of Dynamic SQL by Erland Sommarskog
這將產生最佳的執行計劃:
IF @flag=1
BEGIN
SELECT
[field]
FROM [table]
WHERE col1 = @value
END
ELSE
BEGIN
SELECT
[field]
FROM [table]
WHERE col2 = @different_value
END
然而,如果你必須有一個單一的查詢,這是你使用索引的最佳選擇
SELECT
[field]
FROM [table]
WHERE @flag=1
AND col1 = @value
UNION ALL
SELECT
[field]
FROM [table]
WHERE @flag!=1
AND col2 = @different_value
您還可以使用布爾邏輯:
SELECT blah FROM myTable WHERE (@i IS NULL OR AnotherCondition)
如何簡單;
WHERE
(@flag = 1 AND col1 = @value)
OR
(@flag = 2 AND col2 = @different_value)
...
非常好。第一遍,看起來像是有效的。我會繼續測試,但我認爲這是一個過程。也很簡單。謝謝! – Peter 2010-07-15 15:09:02
這裏沒有索引使用的機會,除非你包含OPTION(RECOMPILE)並且在SQL Server 2008的某個版本上運行,請參閱我的答案中的鏈接[A Service of Service Packs and Cumulative Updates]( http://www.sommarskog.se/dyn-search-2008.html#SPandCUs)。此鏈接解釋了2008年的最新版本如何在考慮到局部變量的運行時間值的情況下重新編譯查詢。如果@flag不是1,並且如果它是1,那麼可以在查詢之外優化「(@flag = 1和col1 = @value)」之類的內容,然後優化爲「col1 = @ value」 – 2010-07-15 15:09:25
我正在運行SQL Server 2005,所以我猜它不會優化。 – Peter 2010-07-15 15:23:03