【问题标题】:SQL use CASE statement in WHERE IN clauseSQL 在 WHERE IN 子句中使用 CASE 语句
【发布时间】:2013-10-16 19:14:18
【问题描述】:

是否可以在 where in 子句中使用 case ? 像这样的:

 DECLARE @Status VARCHAR(50);
 SET @Status='published';

 SELECT * FROM Product P    
 WHERE P.Status IN (CASE WHEN @Status='published' THEN (1,3)
                                   WHEN @Status='standby' THEN (2,5,9,6)
                                   WHEN @Status='deleted' THEN (4,5,8,10)
                                   ELSE (1,3)
                                   END)

此代码给出错误:',' 附近的语法不正确。

【问题讨论】:

  • P.Status 的类型是什么?
  • 您可以在where 中使用case,但不能这样。 Case 每条语句必须返回一个值。
  • @MaryamArshi:P.Status 的类型是 int。
  • @SeanCoetzee。我不明白。可以举个例子吗?
  • 只是问,THEN(2,5,9,6) 有什么意义?

标签: sql select switch-statement case where-in


【解决方案1】:

根据我的场景,我确实“在 WHERE IN 子句中使用 CASE 语句”,如下所示

@AdjType varchar(20) = 'Value', 
@Base varchar(20) = 'Common'
where 
(select CASE WHEN SA.IsPersentage = 0 THEN 'Value' 
       WHEN SA.IsPersentage = 1 THEN 'Presentage' END) Like @AdjType
and (Select CASE WHEN SA.IsDependOnBasicSalary = 0 THEN 'Common' 
        WHEN SA.IsDependOnBasicSalary = 1 THEN 'Basic Salary' END) like @Base

【讨论】:

    【解决方案2】:
     SELECT  * FROM Tran_LibraryBooksTrans LBT  
     LEFT JOIN Tran_LibraryIssuedBooks LIB ON 
     CASE WHEN LBT.IssuedTo='SN' AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1
          WHEN LBT.IssuedTo='SM' AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1 
          WHEN LBT.IssuedTo='BO' AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1
     ELSE 0 END
    

    【讨论】:

      【解决方案3】:

      我相信你可以在 where 子句中使用 case 语句,我是这样做的:

      Select 
      ProductID
      OrderNo,
      OrderType,
      OrderLineNo
      From Order_Detail
      Where ProductID in (
      Select Case when (@Varibale1 != '') 
      then (Select ProductID from Product P Where .......)
      Else (Select ProductID from Product)
      End as ProductID
      )
      

      这种方法一次又一次地对我有用。试试看!

      【讨论】:

      • 它对我有用,创建了一个临时表,根据参数条件插入所需的产品并加入临时表,最后删除了临时表
      【解决方案4】:

      也许你可以试试这个方法

      SELECT * FROM Product P WHERE (CASE WHEN @Status = 'published' THEN (CASE WHEN P.Status IN (1, 3) THEN 'TRUE' ELSE FALSE END) WHEN @Status = 'standby' THEN (CASE WHEN P.Status IN (2, 5, 9, 6) THEN 'TRUE' ELSE 'FALSE' END) WHEN @Status = 'deleted' THEN (CASE WHEN P.Status IN (4, 5, 8, 10) THEN 'TRUE' ELSE 'FALSE' END) ELSE (CASE WHEN P.Status IN (1, 3) THEN 'TRUE' ELSE 'FALSE' END) END) = 'TRUE'

      这样,如果@Status = 'published',查询将检查P.Status 是否在1 或3 之间,否则返回TRUE,否则返回'FALSE'。这将在最后与 TRUE 匹配

      希望对你有帮助。

      【讨论】:

        【解决方案5】:

        不,您不能像这样使用casein。但是你可以做

        SELECT * FROM Product P    
        WHERE @Status='published' and P.Status IN (1,3)
        or @Status='standby' and P.Status IN  (2,5,9,6)
        or @Status='deleted' and P.Status IN (4,5,8,10)
        or P.Status IN (1,3)
        

        顺便说一句,您可以将其减少到

        SELECT * FROM Product P    
        WHERE @Status='standby' and P.Status IN (2,5,9,6)
        or @Status='deleted' and P.Status IN (4,5,8,10)
        or P.Status IN (1,3)
        

        因为or P.Status IN (1,3) 还提供了@Status='published' and P.Status IN (1,3) 的所有记录

        【讨论】:

        • 您不需要在每个“或”子句周围加上括号吗?例如。或(@Status='standby' 和 P.Status IN (2,5,9,6))
        • 不要认为你需要括号,但最后一个or 语句会返回错误的结果......看这个小提琴——不应该返回第二条记录。 sqlfiddle.com/#!3/9aef0/6
        • AND 的优先级高于 OR。这就是在这种情况下不需要括号的原因。
        【解决方案6】:
         select  * from Tran_LibraryBooksTrans LBT  left join
         Tran_LibraryIssuedBooks LIB ON   case WHEN LBT.IssuedTo='SN' AND
         LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1 when LBT.IssuedTo='SM'
         AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1 WHEN
         LBT.IssuedTo='BO' AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1
         ELSE 0 END`enter code here`select  * from Tran_LibraryBooksTrans LBT 
         left join Tran_LibraryIssuedBooks LIB ON   case WHEN LBT.IssuedTo='SN'
         AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1 when
         LBT.IssuedTo='SM' AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN 1
         WHEN LBT.IssuedTo='BO' AND LBT.LIBRARYTRANSID=LIB.LIBRARYTRANSID THEN
         1 ELSE 0 END
        

        【讨论】:

          【解决方案7】:

          我知道这个问题已经得到解答,但是接受的解决方案存在一个小问题。它将返回误报。易于修复:

          SELECT * FROM Products P    
          WHERE (@Status='published' and P.Status IN (1,3))
             or (@Status='standby' and P.Status IN  (2,5,9,6))
             or (@Status='deleted' and P.Status IN (4,5,8,10))
             or (@Status not in ('published','standby','deleted') and P.Status IN (1,2))
          

          不需要括号(尽管可能更容易阅读,因此我将它们包括在内)。

          【讨论】:

            猜你喜欢
            • 2011-03-28
            • 2017-01-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-03-26
            • 1970-01-01
            相关资源
            最近更新 更多