[英]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
可以在某種程度上強制短路表達。
舉例說明為什么要避免使用OR
: http : //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.