NOT EXISTS和NOT IN之间有什么区别,左连接是NULL?
在我看来,你可以在SQL查询中使用NOT EXISTS,NOT IN或LEFT JOIN WHERE IS来做同样的事情。 例如:
SELECT a FROM table1 WHERE a NOT IN (SELECT a FROM table2) SELECT a FROM table1 WHERE NOT EXISTS (SELECT * FROM table2 WHERE table1.a = table2.a) SELECT a FROM table1 LEFT JOIN table2 ON table1.a = table2.a WHERE table1.a IS NULL
我不确定是否所有的语法正确,但这些是我见过的一般技术。 为什么我会select使用一个呢? 性能不同…? 哪一个是最快/最有效的? (如果取决于实施,我什么时候可以使用每一个?)
-
不在与不存在与左join/是空的:SQL Server
-
不在与不存在与左join/是NULL:PostgreSQL
-
不在与不存在与左join/是空的:甲骨文
-
不在与不存在与左join/是空的:MySQL
简而言之:
NOT IN
有点不同:如果列表中只有一个NULL
,它就不匹配。
-
在
MySQL
,NOT EXISTS
效率NOT EXISTS
一些 -
在
SQL Server
,LEFT JOIN / IS NULL
效率较低 -
在
PostgreSQL
,NOT IN
效率较低 -
在
Oracle
,这三种方法都是一样的。
如果数据库擅长优化查询,则前两个将转化为接近第三个的数据。
对于像你这样简单的情况来说,应该没有什么区别,因为它们全部都会作为连接来执行。 在更复杂的查询中,数据库可能无法not in
和not exists
查询中进行联接。 在这种情况下,查询会变慢很多。 另一方面,如果没有可以使用的索引,联接也可能performance不佳,因为使用联接并不意味着你是安全的。 您将必须检查查询的执行计划,以确定是否有任何性能问题。
假设你正在避免空值,它们都是使用标准SQL编写反连接的方法。
使用EXCEPT
是一个明显的EXCEPT
:
SELECT a FROM table1 EXCEPT SELECT a FROM table2
在Oracle中请注意,您需要使用MINUS
运算符(可以说是一个更好的名字):
SELECT a FROM table1 MINUS SELECT a FROM table2
说到专有语法,可能还有非标准的等价物值得研究,这取决于你正在使用的产品,例如在SQL Server中的OUTER APPLY
(类似):
SELECT t1.a FROM table1 t1 OUTER APPLY ( SELECT t2.a FROM table2 t2 WHERE t2.a = t1.a ) AS dt1 WHERE dt1.a IS NULL;
当需要在多字段主键的表中插入数据时,考虑到它会快得多(我在Access中试过,但是我认为在任何数据库中)不要检查“在表中不存在'这样的值'的logging, – 而不是插入到表中,并且多余的logging(通过键)不会被插入两次。
性能视angular总是避免使用反向关键字,如NOT IN,NOT EXISTS,…因为要检查反向项目,DBMS需要遍历所有可用项目并删除反向select。