NOT IN with Nulls - 不清楚的行为[重复]

Posted

技术标签:

【中文标题】NOT IN with Nulls - 不清楚的行为[重复]【英文标题】:NOT IN with Nulls - unclear behaviour [duplicate] 【发布时间】: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)

【问题讨论】:

检查这个:***.com/questions/129077/… @AndreyGordeev:看起来不错。既然你是第一个,请回复一下,我可以把它标记为答案? @iDevlop - 最好将其作为副本关闭?? @iDevlop 因为这个问题是重复的,所以不需要回复 【参考方案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

【讨论】:

虽然不是我的主要问题,但这非常适合我的需求,并且可能是最有效的解决方案。谢谢。

以上是关于NOT IN with Nulls - 不清楚的行为[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Python 操作Redis

python爬虫入门----- 阿里巴巴供应商爬虫

Python词典设置默认值小技巧

《python学习手册(第4版)》pdf

Django settings.py 的media路径设置

Python中的赋值,浅拷贝和深拷贝的区别