2010-07-15 106 views
1

我很想有一個T-SQL語句像下面...CASE語句切換WHERE條件

SELECT [field] 
FROM [table] 
WHERE CASE @flag 
     WHEN 1 THEN col1 = @value 
     ELSE col2 = @different_value 
     END 

問題的關鍵是我想提出一個標誌,在我的功能使用不同的where子句中相同的查詢。我只是無法讓它工作。這可能嗎?

回答

4

這是否適合您?

Where (@flag = 1 and col1 = @value) or (@flag != 1 and col2 = @different_value). 
+0

非常好。第一遍,看起來像是有效的。我會繼續測試,但我認爲這是一個過程。也很簡單。謝謝! – Peter 2010-07-15 15:09:02

+0

這裏沒有索引使用的機會,除非你包含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

+0

我正在運行SQL Server 2005,所以我猜它不會優化。 – Peter 2010-07-15 15:23:03

1

隨着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 

這是不是很不錯的可讀性。請注意性能問題,因爲優化器可能在這裏掙扎。

+0

優化器可能在這裏掙扎。使它工作並使其快速工作(使用索引)通常是完全不同的。 – 2010-07-15 14:57:33

1

基於給定參數的動態改變搜索是一個複雜的問題,並做了一個又一個的方式,即使只有極輕微的不同,可以有巨大的性能影響。關鍵是要使用索引,忽略緊湊的代碼,不要擔心重複的代碼,你必須制定一個好的查詢執行計劃(使用索引)。

閱讀並考慮所有的方法。你最好的方法將取決於您的參數,你的數據,你的模式,你的實際使用情況:

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 
+0

我同意。我會把這些放在「必讀」堆棧中。謝謝回覆。 – Peter 2010-07-15 15:09:40

+0

它「有」是一個查詢,因爲我將它用作接收@flag參數的函數。我將在where子句中測試聯合而不是OR。這是一個相對較小的查詢,所以我不知道它會產生巨大的差異,但很有必要了解使用不同數據集的潛在未來問題。感謝所有的幫助! – Peter 2010-07-15 15:25:26

0

您還可以使用布爾邏輯:

SELECT blah FROM myTable WHERE (@i IS NULL OR AnotherCondition) 
0

如何簡單;

WHERE 
    (@flag = 1 AND col1 = @value) 
OR 
    (@flag = 2 AND col2 = @different_value) 
...