【问题标题】:NOT IN with Nulls - unclear behaviour [duplicate]NOT IN with Nulls - 不清楚的行为[重复]
【发布时间】:2013-08-20 10:38:04
【问题描述】:

以下查询返回 NO 数据:

select * from ediImport 
WHERE glnfact NOT IN (select GLN from Clients)

经过一番搜索,我找到了我想要的数据,这样:

select * from ediImport 
WHERE glnfact NOT IN (select GLN from Clients WHERE gln is not null)

但我觉得第一个查询应该返回信息(我认为它会在 Access 中返回)。
所以我的问题:
- 为什么第一个查询不起作用
- 有没有更好、更有效的方法来做到这一点?我找到了 EXISTS 和 ANY,但我看不出比 old school 方式有任何优势。


注意:我不想在这里使用左连接,因为我真正需要的是执行更新:

UPDATE ediImport SET Status = 2 
WHERE glnfact NOT IN (select GLN from Clients WHERE gln is not null)

【问题讨论】:

  • @AndreyGordeev:看起来不错。既然你是第一个,请回复一下,我可以把它标记为答案?
  • @iDevlop - 最好将其作为副本关闭??
  • @iDevlop 因为这个问题是重复的,所以不需要回复

标签: sql sql-server tsql sql-server-2008-r2 notin


【解决方案1】:

第一个查询因为比较 null values 而没有返回任何数据。 当您比较 2 个值时,结果可能是

  • TRUE 如果它们相等
  • FALSE 如果不是
  • UNKNOWN 如果其中一个或两个值为空

因此,当您使用 not in 时,sql 应该将您的值 glnfact 与子查询中的所有 GLN 值进行比较,如果所有比较都返回 FALSE,那么它会为整个 not in 子句返回 TRUE .如果GLN 的值之一为null,则将其与glnfact 比较返回UNKNOWN,因此not in 子句为UNKNOWN

【讨论】:

    【解决方案2】:

    因您的编辑而回答

    如果你想更新表ediImport中的Status = 2,也就是表Clients中的NULL,你可以在UPDATE这样的语句中使用LEFT JOIN

    UPDATE ei SET ei.Status = 2
      FROM ediImport as ei
      LEFT JOIN Clients c
        ON ei.glnfact = c.gln
     WHERE c.gln IS NULL;
    

    this sample SQLFiddle

    这相当于使用NOT INUPDATE。见this SQLFiddle

    【讨论】:

    • 虽然不是我的主要问题,但这非常适合我的需求,并且可能是最有效的解决方案。谢谢。
    猜你喜欢
    • 2020-12-01
    • 2022-12-01
    • 2012-03-16
    • 2011-03-29
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    • 2014-11-21
    相关资源
    最近更新 更多