内联的对面

问题描述 投票:15回答:4

内连接的反面是什么?对于表格人员(int PersonId, varchar PersoName, int AddrId),我想知道在AddrId表格中没有一行的Address错误的Person中的行。

sql database
4个回答
57
投票

内连接的反面是什么?

OUTER连接,可以有三种选择:

  • 剩下
  • 充分

This is a good visual representation of JOINs

我想知道Person中的行有不好的AddrId,它们在Address表中没有行。

使用LEFT JOIN / IS NULL

   SELECT p.*
     FROM PERSON p
LEFT JOIN ADDRESS a ON a.addrid = p.addrid
    WHERE a.addrid IS NULL

使用NOT EXISTS

SELECT p.*
  FROM PERSON p
 WHERE NOT EXISTS(SELECT NULL
                    FROM ADDRESS a
                   WHERE a.addrid = p.addrid)

使用NOT IN

SELECT p.*
  FROM PERSON p
 WHERE p.addrid NOT IN (SELECT a.addrid
                          FROM ADDRESS a)

7
投票

内部联接不是外部联接的直径。它们用于不同的目的。但是,从一个表中查找不存在于另一个表中的行的常见模式是使用外部联接:

Select ...
From Table1
    Left Join Table2
        On Table2.ForeignKeyCol = Table1.PrimaryKeyCol
Where Table2.PrimaryKeyCol Is Null

这将返回Table1中的所有行以及Table2中的所有匹配行,这样,如果给定的Table1行没有Table2匹配,则返回Table2列的null。然后要求非可空列(Table2.PrimaryKeyCol)为空,我将从Table1获取Table2中不存在的所有行。使用您的示例表名称,我们会有类似的东西:

Select ...
From Person
    Left Join Address
        On Address.PersonId = Person.Id
Where Address.Id Is Null

5
投票

如果将内部联接视为满足特定条件的两个表的行,则相反的是两个表中的行不相符。

例如,以下内容将选择地址表中具有地址的所有人:

SELECT p.PersonName, a.Address
FROM people p
JOIN addresses a
    ON p.addressId = a.addressId

我想这个“相反”就是选择没有地址的所有人和没有人的所有地址。然而,这似乎并不是你所要求的,你似乎只对这个问题的一个组成部分感兴趣:地址表中没有地址的所有人。

为此,左连接最好:

SELECT p.PersonName
FROM people p
LEFT JOIN addresses a
   ON p.addressId = a.addressId
WHERE a.addressId IS NULL

请注意,通常有些人喜欢以不同的方式编写它,因为他们认为它更具可读性(但根据我对大型表的体验,它的表现比上述方式更差):

SELECT PersonName
FROM people
WHERE addressId NOT IN (SELECT addressId FROM addresses)

0
投票

我认为最好的解决方案是使用EXISTS。像这样:

SELECT * FROM Person P
WHERE P.AddrId IS NOT NULL 
  AND NOT EXISTS ( SELECT 1 FROM Address A WHERE A.AddrId = P.AddrId )

上面的查询将返回AddrId设置但在Address表中没有相应记录的每个人。

Obs。:使用EXISTS查询中的常量1来避免表访问。

© www.soinside.com 2019 - 2024. All rights reserved.