【问题标题】:Using an 'IN' predicate with CASE statements in the WHERE clause for SQL Server在 SQL Server 的 WHERE 子句中使用带有 CASE 语句的“IN”谓词
【发布时间】:2013-01-17 17:14:19
【问题描述】:

这是一个运行良好的 SQL 查询:

DECLARE @IncludePTO AS CHAR
SET @IncludePTO = 'Y'

SELECT     
   HQCO.HQCo, HQCO.Name, PREH.PRDept, PREH.Craft, HRRM.PositionCode, PRTH.Employee, 
   PREH.LastName, PREH.FirstName, SUM(PRTH.Hours) AS Hrs
FROM PREH 
INNER JOIN HRRM ON PREH.PRCo = HRRM.HRCo AND PREH.Employee = HRRM.HRRef 
INNER JOIN PRTH ON PREH.PRCo = PRTH.PRCo AND PREH.Employee = PRTH.Employee 
INNER JOIN HQCO ON PRTH.PRCo = HQCO.HQCo
WHERE     
    (dbo.PRTH.PREndDate BETWEEN '1/1/2012 00:00:00' AND '1/1/2013 00:00:00')
    AND (PRGroup = 2)
    AND dbo.PRTH.EarnCode IN (1,3,8)
GROUP BY 
    HQCO.HQCo, HQCO.Name, PREH.PRDept, PREH.Craft, 
    HRRM.PositionCode, PRTH.Employee, PREH.LastName, PREH.FirstName

但是,我正在尝试在 WHERE 子句中使用“IN”谓词和 CASE WHEN。看看下面修改后的查询:

DECLARE @IncludePTO AS CHAR
SET @IncludePTO = 'Y'

SELECT     
   HQCO.HQCo, HQCO.Name, PREH.PRDept, PREH.Craft, HRRM.PositionCode, PRTH.Employee, 
   PREH.LastName, PREH.FirstName, SUM(PRTH.Hours) AS Hrs
FROM PREH 
INNER JOIN HRRM ON PREH.PRCo = HRRM.HRCo AND PREH.Employee = HRRM.HRRef 
INNER JOIN PRTH ON PREH.PRCo = PRTH.PRCo AND PREH.Employee = PRTH.Employee 
INNER JOIN HQCO ON PRTH.PRCo = HQCO.HQCo
WHERE     
    (dbo.PRTH.PREndDate BETWEEN '1/1/2012 00:00:00' AND '1/1/2013 00:00:00')
    AND (PRTH.PRGroup = 2)
    AND 
       CASE WHEN @IncludePTO = 'Y' THEN dbo.PRTH.EarnCode IN (1,2,3,8,100,110,120,115)
            ELSE dbo.PRTH.EarnCode IN (1,2,3,8)
       END
GROUP BY 
    HQCO.HQCo, HQCO.Name, PREH.PRDept, PREH.Craft, HRRM.PositionCode, PRTH.Employee, 
    PREH.LastName, PREH.FirstName

它似乎不起作用并不断给我一个语法错误:

消息 156,第 15 级,状态 1,第 15 行
关键字“IN”附近的语法不正确。

在指出我缺少什么方面有任何帮助或指导吗?非常感谢任何帮助/提示。非常感谢,

普拉纳夫

【问题讨论】:

    标签: sql where case-when


    【解决方案1】:

    你是对的。不允许使用该语法。你可以试试:

    ((@IncludePTO = 'Y' and dbo.PRTH.EarnCode IN (1,2,3,8,100,110,120,115)) or
     (@IncludePTO <> 'Y' and dbo.PRTH.EarnCode IN (1,2,3,8))
    )
    

    这可以简化为:

    (bo.PRTH.EarnCode IN (1,2,3,8) or (@IncludePTO <> 'Y' and dbo.PRTH.EarnCode IN (100,110,120,115))
    )
    

    这假定@IncludePTO 永远不会为NULL。如果是这样,那么这将是测试的一部分。

    如果你真的想要where子句中的case语句,你可以这样做:

    (CASE WHEN @IncludePTO = 'Y' and dbo.PRTH.EarnCode IN (1,2,3,8,100,110,120,115)
          then 'true'
          when @IncludePTO <> 'Y' and dbo.PRTH.EarnCode IN (1,2,3,8)
          then 'true'
          else 'false'
     end) = 'true'
    

    【讨论】:

    • 效果很好!非常感谢戈登!!我欠你很多时间!!
    猜你喜欢
    • 1970-01-01
    • 2013-10-16
    • 2021-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-30
    • 2013-12-06
    相关资源
    最近更新 更多