【问题标题】:Case Statement in 'IN' clause in SQLSQL中'IN'子句中的Case语句
【发布时间】:2014-12-31 22:54:54
【问题描述】:

我正在尝试在 IN 子句中编写 case 语句。

Channel 列包含三个值 ACT、REN、REP。我想选择超过 1 个值,但我得到的结果只有一个值。

    select * from tbl
    WHERE tbl.Channel IN (select 
                                    case when @ACT =1 then 'ACT'
                                    when @REN =1 then 'REN' 
                                    when @REP =1 then 'REP' END)

我应该在这里做些什么改变?

【问题讨论】:

  • 您使用的是 MySQL 还是 SQL Server?请仅标记您实际使用的平台。当您将鼠标悬停在这些标签上时,它们会有描述;请在使用前阅读它们。
  • @AaronBertrand 我最近看到了很多。可能是因为这个meta.stackoverflow.com/questions/275170/…
  • @Martin 可能是。另请参阅meta.stackexchange.com/questions/207274/… 和 Shog 的回答 here 下的讨论。
  • @AaronBertrand 希望他们扩展新的标签提示功能,使其更加智能并识别特定的 RDBMS 平台,这样它就不会在已标记时向您发出警告。那么我想这将是一个很短的步骤来识别你有多个标记。

标签: mysql sql sql-server


【解决方案1】:

不要结束你的案子。您将返回 3 列。你只想要一个。

select * from tbl
    WHERE tbl.Channel =  case when @ACT =1 then 'ACT' 
                              when @REN =1 then 'REN'
                              when @REP =1 then 'REP' 
                              else NULL END

【讨论】:

  • 那么会先返回ACT。
  • 我想从 REn、REP 和 ACT 中选择多个选项。在这里,我只得到 1 个值
【解决方案2】:

这会很好。 SQL Fiddle

唯一的变化是删除select,因此 in 子句的输入是 3 个值,而不是包含三列的单行。

如果变量不是 1,则隐含的 else null 不会导致 in 子句出现问题。

SELECT * 
FROM   tbl 
WHERE  tbl.channel IN ( CASE 
                          WHEN @ACT = 1 THEN 'ACT' 
                        END, CASE 
                          WHEN @REN = 1 THEN 'REN' 
                        END, CASE 
                               WHEN @REP = 1 THEN 'REP' 
                             END ) 

【讨论】:

    【解决方案3】:

    这是一个替代方案,可以让您在没有 IN 运算符的情况下执行选择:

    select * from tbl
    WHERE (tbl.Channel='ACT' AND @ACT=1)
       OR (tbl.Channel='REN' AND @REN=1)
       OR (tbl.Channel='REP' AND @REP=-1)
    

    如果您必须使用IN 运算符,您应该能够使用UNION ALL 构造查询,如下所示:

    select * from tbl
    WHERE tbl.Channel IN (
        select case when @ACT =1 then 'ACT' END FROM DUAL
            UNION ALL
        select case when @REN =1 then 'REN' END FROM DUAL
            UNION ALL
        select case when @REP =1 then 'REP' END FROM DUAL)
    

    Demo.

    【讨论】:

      【解决方案4】:

      您可以编写不带case 的子句:

      select *
      from tbl
      where (tbl.Channel 'ACT' and @ACT = 1) or
            (tbl.Channel = 'REN' and @REN = 1) or
            (tble.Channel = 'REP' and @REP = 1);
      

      您的select 语句不正确,应该返回错误。 in 子句中的 select 语句不允许返回多于一列。

      【讨论】:

      • 在组合 AND 和 OR 时,您确实应该使用括号来明确所需的逻辑树。
      猜你喜欢
      • 1970-01-01
      • 2013-10-16
      • 2013-10-03
      • 1970-01-01
      • 2020-03-26
      • 1970-01-01
      • 1970-01-01
      • 2018-10-27
      • 2011-08-27
      相关资源
      最近更新 更多