【问题标题】:SQL Server 2008 not in nullSQL Server 2008 不为空
【发布时间】:2012-01-17 01:50:54
【问题描述】:

我在执行以下操作时遇到了一个奇怪的错误:

SELECT *
FROM table1
WHERE NAME COLLATE LATIN1_General_CI_AS NOT IN (select name FROM table2)

Namenvarchar(50) nullTable2name 列中有 null 值。然后它将匹配 table2 中不存在的名称,因为 null 值。这意味着这将返回 0 结果。如果我这样做了:

SELECT *
FROM table1
WHERE NAME COLLATE LATIN1_General_CI_AS NOT IN (
  select name FROM table2 where name is not null
)

我会得到一些结果。

一张表有排序规则Danish_Norwegian_CI_AS,另一张表有排序规则latin1。也许COLLATE 是问题的根源?

谁能解释为什么会这样?也许有集合论的东西?

【问题讨论】:

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


    【解决方案1】:

    它与排序规则无关。尝试set ansi_nulls off,第一个查询将按预期工作。

    原因是当您尝试将某些内容与 NULL 进行比较时(例如 a = NULL 或 NULL),结果为 UNKNOWN 并且整个查询失败。如果您将 ansi_nulls 设置为 off,则相同的比较结果为 TRUE 或 FALSE,并且查询“有效”。

    换句话说:

    WHEN a NOT IN (1, 2, null)
    

    意思

    WHEN a <> 1 AND a <> 2 AND a <> null
    

    WHERE 最后一部分 a &lt;&gt; null 的计算结果为 UNKNOWN,查询未能返回任何行。

    【讨论】:

      【解决方案2】:

      我想我会使用

      来解决这个问题
      SELECT * 
        FROM table1 t1
       WHERE NOT EXISTS ( SELECT *
                            FROM table2 t2
                           WHERE (t1.NAME COLLATE LATIN1_General_CI_AS = t2.name)
                              OR (t1.NAME IS NULL AND t2.name IS NULL))
      

      没有花哨的理论,只是实践经验=P

      【讨论】:

        【解决方案3】:

        NULLNOT INNOT EXISTS 表达式中使用时无法正常工作。

        基本上,如果子集包含NULL,SQL Server 不能肯定某物不在子集中,因为NULL 是具有未知值的状态。

        我认为排序规则甚至没有进入它,查询是不同的。

        See a full explanation of NULL in NOT IN here.

        【讨论】:

          猜你喜欢
          • 2011-02-16
          • 1970-01-01
          • 1970-01-01
          • 2010-11-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-23
          • 2011-04-20
          相关资源
          最近更新 更多