3

我想完成以下工作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吗?

4

4 回答 4

7

CASE 是一个返回单个值的表达式。它不用于流量控制。

WHERE (Column1 = @Value AND @chk = 'Y')
OR (@chk <> 'Y' AND Column1 IN (SELECT column2 FROM table2));
于 2012-05-25T12:44:18.657 回答
4

CASE用于表达式的内联求值。这不是真正的动态WHERE子句。

您所要求的解决方案是使用WHERE按括号分组的子句:

 Select * From Table1 
 Where 
 (@chk='Y' AND Column1=@Value)
 OR
 (@chk <> 'Y' AND Column1 In (Select column2 from Table2))
于 2012-05-25T12:44:13.223 回答
1

我们也可以这样做,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 将如何实际执行您的查询。您的 RDBMS 在使用CASE WHEN. 最好的规则仍然是分析您的查询

于 2012-05-25T15:06:13.357 回答
0

可以在 WHERE 子句中使用 Case 语句。他们这样做的方式是:

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

通常,您不想这样做,主要是出于审美原因。也就是说,在某些情况下,使用 case 编写的代码比使用 where 中的相应逻辑更具可读性。事实上,这可能是这样的情况。

但是,更重要的是,您出于性能或语法原因想要短路的情况。使用 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

就个人而言,当遇到这种情况时,我更喜欢将 case 放在子查询中,因此 WHERE 将包含列名。

于 2012-05-25T14:03:55.363 回答