SQL概念LEFT OUTER JOIN和WHERE NOT EXISTS基本相同吗?

时间:2012-03-19 18:22:53

标签: sql database join left-join

使用LEFT OUTER JOIN而不是以WHERE NOT EXISTS (...)开头的子查询有什么不同?

5 个答案:

答案 0 :(得分:34)

不,它们不是一回事,因为它们在最简单的用例中返回相同的行集。

LEFT OUTER JOIN将返回左表中的所有行,包括相关表中存在的行和不存在的行。 WHERE NOT EXISTS()子查询只返回不满足关系的行。

但是,如果您在LEFT OUTER JOIN子句中的外键列上执行IS NULL并查找WHERE,则可以对WHERE NOT EXISTS进行等效行为。

例如:

SELECT 
  t_main.*
FROM 
   t_main
   LEFT OUTER JOIN t_related ON t_main.id = t_related.id
/* IS NULL in the WHERE clause */
WHERE t_related.id IS NULL

相当于:

SELECT
  t_main.*
FROM t_main 
WHERE 
  NOT EXISTS (
    SELECT t_related.id 
    FROM t_related 
    WHERE t_main.id = t_related.id
  )

但是这个不等于

它将从t_main返回t_related中包含和没有相关行的行。

SELECT 
  t_main.*
FROM
  t_main
  LEFT OUTER JOIN t_related ON t_main.id = t_related.id
/* WHERE clause does not exclude NULL foreign keys */

注意这并不是说如何编译和执行查询,这也有所不同 - 这只会解决它们返回的行集的比较。

答案 1 :(得分:5)

正如迈克尔已经回答了你的问题,这是一个快速的例子来说明差异:

Table A
Key     Data
1       somedata1
2       somedata2

Table B
Key     Data
1       data1

左外连接:

SELECT *
FROM A
LEFT OUTER JOIN B
ON A.Key = B.Key

结果:

Key     Data        Key     Data
1       somedata1   1
2       somedata2   null    null

EXISTS使用:

SELECT *
FROM A WHERE EXISTS ( SELECT B.Key FROM B WHERE A.Key = B.Key )

不存在于:

SELECT *
FROM A WHERE NOT EXISTS ( SELECT B.Key FROM B WHERE A.Key = B.Key )

结果:

Key     Data        
2       somedata2

答案 2 :(得分:2)

左外连接比不存在时更灵活。如果要从子表中返回任何列,则必须使用左外连接。您还可以使用左外连接返回与父表匹配的记录以及父表中没有匹配的所有记录。如果不存在,则只允许您返回没有匹配的记录。

但是,在它们确实返回等效行并且您不需要右表中的任何列的情况下,那么存在可能是更高性能的选择(至少在SQL服务器中,我不了解其他dbs。)

答案 3 :(得分:0)

我怀疑答案最终是,两者都在(在其他构造中)用于在SQL中执行关系操作antijoin

答案 4 :(得分:0)

我怀疑OP希望知道在功能上相同的哪个构造更好(即,我只想查看辅助表中没有匹配项的行)。

因此,“不存在”总是会变得越来越快,因此养成良好的习惯。