【问题标题】:Case not working in Exists in Sql Server案例不工作在 Sql Server 中存在
【发布时间】:2012-08-28 00:34:41
【问题描述】:

我有一个场景,我必须检查一个变量的默认值,如果它有我必须使用 Table2 有条件地检查 EXISTS 部分,如果它没有默认值,我必须有条件地检查 EXISTS 部分表 3。

下面是示例代码:-

SELECT * FROM tbl1 WHERE EXISTS (SELECT CASE WHEN @boolVar = 0 THEN (SELECT 'X' FROM tbl2 WHERE tbl1.col1 = tbl2.col1) ELSE (SELECT 'X' FROM tbl3 where tbl1.col1 = tbl3.col1) END)

用于测试目的的带有常量的演示查询:-

SELECT 1 WHERE EXISTS (SELECT CASE WHEN 1 = 0 THEN (SELECT 'X' WHERE 1=0) 
    ELSE (SELECT 'X' WHERE 1 = 2) END)

注意:- 上面的查询总是返回 1,甚至没有一个条件满足。

我知道我们可以使用 OR 运算符,以及我们如何实现它,但我真的想知道,如果两个表都没有满足其特定 where 子句的行,即使它返回 Table1 中的所有行.

我试图用常量值的演示查询来解释这一点。

请帮忙。

【问题讨论】:

  • SELECT CASE WHEN 1 = 0 THEN (SELECT 'X' WHERE 1=0) ELSE (SELECT 'X' WHERE 1 = 2) END 返回一行。 EXISTS 对此进行检查。它返回一个恰好是 NULL 的列并不重要
  • 您的演示查询将始终在子查询中返回 NULL,因为它不匹配任何 where 条件
  • 我不确定您提供的查询是否会返回 1,因为没有任何条件匹配
  • 是的@MartinSmith,我同意你的观点并进行了测试,但我不明白为什么它要重排一个有 NULL 的行。
  • 是的@AnandPhadke,我同意你的观点,并且也进行了同样的测试,但我仍然无法理解为什么它会重新调整具有 NULL 的行,即使上述任何一个都没有单独的一行。

标签: sql-server sql-server-2008 sql-server-2005 sql-server-2008-r2 sql-server-2000


【解决方案1】:

当您的查询没有找到任何匹配的记录时,它基本上会这样做:

SELECT 1 WHERE EXISTS (SELECT NULL)

由于包含空值的行仍然是行,EXISTS 命令返回 true。

可以添加条件过滤掉空行:

SELECT * FROM tbl1 WHERE EXISTS (
  SELECT 1 FROM (
    SELECT
      CASE WHEN @boolVar = 0 THEN (SELECT 'X' FROM tbl2 WHERE tbl1.col1 = tbl2.col1)
      ELSE (SELECT 'X' FROM tbl3 where tbl1.col1 = tbl3.col1)
      END AS Y
  ) Z
  WHERE Y IS NOT NULL
)

【讨论】:

  • 嗨@Guffa,感谢您的建议,但我仍然不明白为什么它会重新搜索具有 NULL 的行,即使查询的上述部分都没有单独返回单行。
  • @GKRanjan - SELECT CASE ... 没有 where 子句将始终返回包含表达式结果的单行。
  • @GKRanjan:这是因为您选择了包含case 表达式中的值的一行,所以无论case 返回什么,总会有一行。 exists 函数只检查是否有行,并不关心行包含什么。
  • 感谢@MartinSmith 的澄清
  • 感谢@Guffa 的澄清
【解决方案2】:

这里有一个替代方案,以防万一:

SELECT *
FROM Table1
WHERE EXISTS (
  SELECT 1
  FROM Table2
  WHERE @var = @defValue
    AND ... /* other conditions as necessary */
  UNION ALL
  SELECT 1
  FROM Table3
  WHERE @var <> @defValue
    AND ... /* other conditions as necessary */
);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    • 2014-10-17
    相关资源
    最近更新 更多