2011-11-16 160 views
3

我想在SQL Server(存儲過程)中執行CASE語句,我應該檢查它是否應該從另一個表中獲取一些結果。SQL Server:案例與聲明「不在」

我只是做這件事來說明示例(不工作!)

SELECT 
    * 
FROM 
    cards 
WHERE 
    CardID = @CardID 
    AND 
    CardID = 
     CASE WHEN @AlreadyOnDeck = 1 THEN 
      IN (
        SELECT CardID FROM OnDeckTable WHERE CardID = @CardID 
      ) 
     CASE WHEN @AlreadyOnDeck = 0 THEN 
      NOT IN (
        SELECT CardID FROM OnDeckTable WHERE CardID = @CardID 
      ) 
     END 

我需要的情況下IN/NOT IN取決於@AlreadyOnDeck可變

+1

要動態生成應包含如果@AlreadyOnDeck是1而不是0,如果SQL語句的一部分嗎? –

+0

IIRC您無法通過使用SELECT獲取值來填充IN。 – Treborbob

回答

2

與Max的答案類似,但使用CASE語句。 (可能會產生一個稍微好一點的執行計劃由於外CASE語句的短路。)

SELECT 
    * 
FROM 
    cards c 
WHERE 
    c.CardID = @CardID 
    AND 
    1 = (CASE WHEN @AlreadyOnDeck = 1 THEN 
        (CASE WHEN EXISTS(select * OnDeckTable dt where dt.CardID = c.CardID) THEN 1 END) 
       WHEN @AlreadyOnDeck = 0 THEN 
        (CASE WHEN NOT EXISTS(select * from OnDeckTable dt where dt.CardID = c.CardID) THEN 1 END)  
     END) 
2

我認爲這會工作,但避風港未經測試(未提供測試數據)。

SELECT 
    * 
FROM 
    cards 
WHERE 
    CardID = @CardID 
    AND 
    (
     exists (select 1 from OnDeckTable where CardId = @CardId and @AlreadyOnDeck = 1) 
     or not exists (select 1 from OnDeckTable where CardId = @CardId and @AlreadyOnDeck = 0) 
    ) 
2
SELECT 
    * 
FROM 
    cards crd 
WHERE 
    CardID = @CardID 
    AND 
    (
    (@AlreadyOnDeck = 1 AND EXISTS(SELECT 1 FROM OnDeckTable dt WHERE dt.CardID = crd.CardID)) 
    OR 
    (@AlreadyOnDeck = 0 AND NOT EXISTS(SELECT 1 FROM OnDeckTable dt WHERE dt.CardID = crd.CardID)) 
    ) 
+0

我認爲@DerekKromm的答案也有效,與此非常相似。儘管如此,句子組織在這個答案中有更多的意義和可讀性。 – daniloquio

+0

是的,我同意。我已經給@ DerekKromm的答案加了+1。 – Max

1

我將與加入像這樣做:

SELECT * 
FROM cards c 
LEFT JOIN OnDeckTable o ON c.CardID = o.CardID 
WHERE c.CardID = @CardID 
    AND (((@alreadyOnDeck = 0) AND (o.CardID is not null)) OR 
     ((@alreadyOnDeck = 1) AND (o.CardID is null))) 

我相信這將是比子查詢更快存在的建議,但我沒有測試過。

另外請注意,我沒有測試上面的代碼,它可能有錯別字。

解決這個最快的方法是在一個以包住,如果爲@alreadyOnDeck變量,類似這樣的語句:

if (@alreadyOnDeck = 1) 
    -- select for this case 
else 
    -- select for this case. 

如果你的代碼是在存儲過程中,這將是最快的方式,輸入是在查詢期間不會改變。