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

Ste*_*ris 13 sql database join left-join

是什么区别使用a LEFT OUTER JOIN而不是以a开头的子查询WHERE NOT EXISTS (...)

Mic*_*ski 38

不,它们不是同一个东西,因为它们不会在最简单的用例中返回相同的行集.

LEFT OUTER JOIN将返回左表中的所有行,无论是中行在相关表中存在和他们没有.该WHERE NOT EXISTS()子查询只会返回我们的关系不符合行.

但是,如果您在子句中的外键列上执行了a LEFT OUTER JOIN和查找,则可以对其进行等效行为. IS NULLWHEREWHERE 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
Run Code Online (Sandbox Code Playgroud)

相当于:

SELECT
  t_main.*
FROM t_main 
WHERE 
  NOT EXISTS (
    SELECT t_related.id 
    FROM t_related 
    WHERE t_main.id = t_related.id
  )
Run Code Online (Sandbox Code Playgroud)

但这个等同于:

它将从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 */
Run Code Online (Sandbox Code Playgroud)

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

  • 只是澄清一下:`LEFT OUTER JOIN`将返回**左**表中的所有行; 右表中可能存在不会返回的行. (2认同)

ntz*_*lis 5

由于迈克尔已经回答了您的问题,因此这里有一个简单的例子来说明区别:

Table A
Key     Data
1       somedata1
2       somedata2

Table B
Key     Data
1       data1
Run Code Online (Sandbox Code Playgroud)

左外连接:

SELECT *
FROM A
LEFT OUTER JOIN B
ON A.Key = B.Key
Run Code Online (Sandbox Code Playgroud)

结果:

Key     Data        Key     Data
1       somedata1   1
2       somedata2   null    null
Run Code Online (Sandbox Code Playgroud)

存在用途:

SELECT *
FROM A WHERE EXISTS ( SELECT B.Key FROM B WHERE A.Key = B.Key )
Run Code Online (Sandbox Code Playgroud)

不存在于:

SELECT *
FROM A WHERE NOT EXISTS ( SELECT B.Key FROM B WHERE A.Key = B.Key )
Run Code Online (Sandbox Code Playgroud)

结果:

Key     Data        
2       somedata2
Run Code Online (Sandbox Code Playgroud)

  • @HLGEM可以肯定地使用了*,因为它指出了第二个差异(返回的列较少) (3认同)
  • 当然,您通常不应该在生产代码中使用select *。 (2认同)