【问题标题】:SQL: Check for 'value' is not null returns TRUE when 'value' is nullSQL:检查 'value' 是否为 null 当 'value' 为空时返回 TRUE
【发布时间】:2014-10-31 14:31:23
【问题描述】:

我使用的是 SQL Server 2008,当我对外部表没有任何记录的表执行左连接时,我在 where 子句中看到了奇怪的行为。如果我检查外部表中的值是否为“非空”,它有时会返回 true。

select *
from foo f left join bar b on b.id=f.id
where f.id=@id and (f.status = 1 or b.Price is not null)

当我的 f.status = 0b.Price 不存在(或者,在选择中显示为 null)时,此查询将选择 f.status = 0b.Price is null 的记录,即使 (FALSE OR FALSE) 应该为 FALSE。

如果我只是执行此查询,它会按预期工作,并且不会选择“bar”中没有记录的任何内容。

select *
from foo f left join bar b on b.id=f.id
where f.id=@id and b.Price is not null

b.Price is not null 作为or 操作的一部分似乎由于某种原因导致了问题。这个查询可能有什么问题?我在 SQL Server 2012 机器上使用类似数据运行相同的查询,但没有看到这个问题,这可能与我使用的 SQL Server 版本有关吗?

【问题讨论】:

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


    【解决方案1】:

    正如您所发现的,这两个公式相同。

    在第一个查询中,price 可以是 NULL,原因有两个:

    • 没有来自left join 的匹配项。
    • 有一个匹配项,b.Price 为空

    我强烈推荐第二种方法,将条件放在on 子句中。但是,如果您确实使用第一个,请与 join 中使用的列进行比较:

    where f.id = @id and (f.status = 1 or b.id is not null)
    

    【讨论】:

      【解决方案2】:

      你可以试试这样的OUTER APPLY

      SELECT *
      FROM foo f
      OUTER APPLY (
      SELECT *
      FROM bar b
      WHERE f.id = b.id
          AND (
              f.STATUS = 1
              OR b.Price IS NOT NULL
              ) b
      )
      WHERE f.id = @id
      

      而且我还建议使用列而不是 *,这是不好的做法。 Outer Apply 有点像左连接,在这种情况下,它将过滤条形表中的所有数据并只带回您需要的数据。

      【讨论】:

        【解决方案3】:

        CASE 语句会起作用吗?

        IE

        选择

        (等等等等代码)

        CASE WHEN b.Price 不为空 THEN 1 ELSE 0 END AS [MyBooleanCheck]

        FROM(等等等等代码)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-25
          • 2015-03-23
          • 1970-01-01
          • 2015-05-29
          相关资源
          最近更新 更多