簡體   English   中英

如何在SQL Server上的CASE中使用“IN”?

[英]How to use “IN” in CASE on SQL server?

我希望從case when完成以下內容

If @chk='Y'  
    Select * From Table1 Where Column1=@Value  
Else If (@chk='N')
    Select * From Table1 Where Column1 In (Select column2 from Table2)

我想它可能是這樣的:

 Select * 
 From Table1 
 Where 
    Case  When @chk='Y' Then
        Column1=@Value
    Else
        Column1 In (Select column2 from Table2)
 End

我知道除了Case When之外還有其他解決方案。 但是,使用Case when可以做到這一點嗎?

CASE是一個返回單個值的表達式。 它不用於控制流量。

WHERE (Column1 = @Value AND @chk = 'Y')
OR (@chk <> 'Y' AND Column1 IN (SELECT column2 FROM table2));

CASE用於表達式的內聯評估。 它不是真正的動態WHERE子句。

您要問的解決方案是使用括號分組的WHERE子句:

 Select * From Table1 
 Where 
 (@chk='Y' AND Column1=@Value)
 OR
 (@chk <> 'Y' AND Column1 In (Select column2 from Table2))

我們也可以用CASE WHEN做它,它可能是理想的。 我在這個問題回答了一個類似的問題( 一列表中的三個條件

Select * From Table1 
Where 
   CASE @Chk
   WHEN 'Y' THEN
        CASE WHEN Column1=@Value THEN 1 END 
   WHEN 'N' THEN
        CASE WHEN Column1 In (Select column2 from Table2) THEN 1 END
   END = 1

CASE可以在某種程度上強制短路表達。

舉例說明為什么要避免使用ORhttp//www.sqlfiddle.com/#!6/29531/2

鑒於這兩個功能相同的查詢:

-- using CASE WHEN to convince your RDBMS to short-circuit things:
select count(*)
from usermessages um
join "user" u    
on
(case when um.friendId = 1 then um.sourceUserId else um.friendId end) = u.userId;


-- pure boolean approach, RDBMS can't short-circuit the OR expression
select count(*)
from usermessages um
join "user" u    
on 
(um.friendId = 1 and um.sourceUserId = u.userId)
or 
(um.friendId = u.userId);

根據http://www.sqlfiddle.com/#!6/29531/2的樣本數據,第一個查詢只花了88毫秒,而第二個查詢花了4.7秒。 用戶可以非常感知速度的差異。

這不是一個嚴格的規則,您仍然必須檢查您的RDBMS將如何實際執行您的查詢。 使用CASE WHEN時,您的RDBMS可能仍然無法進行出價(短路)。 最好的規則仍然是分析您的查詢

可以在WHERE子句中使用Case語句。 他們這樣做的方式是:

Select *
From Table1
Where (Case When @chk='Y' and Column1=@Value the 'Y'
            Else Column1 In (Select column2 from Table2)
       End) = 'Y'

通常,您不希望這樣做,主要是出於審美原因。 也就是說,可能存在這樣的情況:使用案例編寫的代碼比使用其中的相應邏輯更具可讀性。 事實上,這可能就是這種情況。

但更重要的是,您希望因性能原因或語法而短路。 使用WHERE子句幾乎可以保證子查詢的評估。 它可能不會使用CASE執行。

錯誤是另一種情況。 當列不是數字時,以下內容可能會生成SQL類型錯誤,因為SQL不保證WHERE中子句的順序:

where isnumeric(val) = 1 and cast(val to float) < 100.0

另一方面,以下工作:

where (case when isnumeric(val) = 1 then cast(val to float) end) < 100.0

就個人而言,當遇到這種情況時,我更喜歡將案例放在子查詢中,因此WHERE將包含列名。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM