【问题标题】:Issue while using 'case when ' in 'where' clause sql server在'where'子句sql server中使用'case when'时出现问题
【发布时间】:2016-05-13 06:22:09
【问题描述】:

在sql查询的where子句中使用case时它不起作用。

问题:

我有两个名为 TblEmployee 和 TblAssociate 的表。这两个表都包含公共列 PeriodId、EmpId 和 AssociateId。我的要求是从 应排除 TblAssociate 中的 EmpId 和 AssociateId 组合的 TblEmployee。排除应基于 PeriodId 条件。`

If(@PeriodID<50)
BEGIN
  SELECT * 
  FROM TblEmployee 
  WHERE (EmpId+AssociateId) NOT IN (SELECT EmpId+AssociateId FROM TblAssociate)
END
ELSE
BEGIN
  SELECT * 
  FROM TblEmployee 
  WHERE (EmpId) NOT IN (SELECT EmpId FROM TblAssociate)
END

上面的代码是有效的,但我需要避免 IF-ELSE 条件,我希望在 where 子句中使用“case when”。请帮助

【问题讨论】:

  • 你为什么使用+,而不是AND?这可能会导致错误的结果。

标签: sql-server database sql-server-2008


【解决方案1】:

试试这个:

SELECT * 
FROM TblEmployee 
WHERE (EmpId + CASE WHEN @PeriodID<50 THEN AssociateId ELSE 0 END) NOT IN 
      (SELECT EmpId + CASE WHEN @PeriodID<50 THEN AssociateId ELSE 0 END FROM TblAssociate)

您说您的代码正在运行,但这很奇怪,因为将 id 值加在一起没有多大意义。无论如何,上述语句产生的结果与最初发布的代码相同。

【讨论】:

    【解决方案2】:

    您可以在WHERE 子句中使用AND-OR 组合。此外,您不应该使用+,因为它可能会导致错误的结果。您可以将查询重写为:

    SELECT e.*
    FROM TblEmployee e
    WHERE
        (
            @PeriodID < 50 
            AND NOT EXISTS(
                SELECT 1 
                FROM TblAssociate a 
                WHERE 
                    a.EmpId = e.EmpId
                    AND a.AssociateId = e.AssociateId
            )
        )
        OR 
        (
            @PeriodID >= 50 
            AND NOT EXISTS(
                SELECT 1 
                FROM TblAssociate a 
                WHERE a.EmpId = e.EmpId
            )
        )
    

    【讨论】:

      【解决方案3】:

      添加 ID 并不能保证唯一性。例如,如果 EmpId 是 5,AssociateId 是 6,那么 EmpId + AssociateId = 11,而 EmpId + AssociateId = 11,即使 EmpId 是 6 而 AssociateId 是 5 . 在下面的查询中,我确保子查询将在找到第一条记录时停止搜索,并返回一条记录,其值为1。当且仅当1 在结果中时,我们才会选择员工。在子查询中,我们首先检查我们确定的操作数,然后检查我们是否不在必须检查AssociateId 的时期,或者它匹配。

      select *
      from TblEmployee
      where 1 in (select top 1 1
                  from TblAssociate
                  where TblEmployee.EmpId = TblAssociate.EmpId and
                  (@PeriodID >= 50 or TblEmployee.AssociateId = TblAssociate.AssociateId))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多