加入"存在"子查询

Tyl*_*ler 3 sql t-sql sql-server join

我想知道为什么当你在存在子查询中的一个键上连接两个表时,连接必须在WHERE子句而不是FROM子句中发生.

这是我的例子:

加入FROM子句:

SELECT payer_id
  FROM Population1
 WHERE NOT EXISTS
       (Select *
          From Population2 join Population1 
            On Population2.payer_id = Population1.payer_id)
Run Code Online (Sandbox Code Playgroud)

加入WHERE子句:

SELECT payer_id
  FROM Population1
  WHERE NOT EXISTS
        (Select *
           From Population2
          WHERE Population2.payer_id = Population1.payer_id)
Run Code Online (Sandbox Code Playgroud)

第一个查询给出了0个结果,我知道这是不正确的,而第二个查询给出了我期望看到的数千个结果.

有人可以向我解释为什么连接在EXISTS子查询中发生的事情很重要吗?如果你在没有父查询的情况下获取子查询并运行它们,它们会给你相同的结果.

在使用存在时,记住不要继续犯这个错误会帮助我很多.

提前致谢.

Gor*_*off 6

您需要了解常规子查询和相关子查询之间的区别.

使用您的示例,这应该很容易.第一个where条款是:

where not exists (Select 1
                  from Population2 join
                       Population1
                       on Population2.payer_id = Population1.payer_id
                 )
Run Code Online (Sandbox Code Playgroud)

这种情况正如它所说的那样.子查询与外部查询没有任何关联.因此,not exists将过滤掉所有行或保留所有行.

在这种情况下,引擎运行子查询并确定至少返回一行.因此,not exists在所有情况下都返回false,并且不返回任何内容.

在第二种情况下,子查询是相关子查询.因此,对于population1子查询中的每一行都使用值来运行Population1.payer_id.在某些情况下,匹配的行存在于Population2; 这些被过滤掉了.在其他情况下,匹配的行不存在; 这些都在结果集中.