内联的对面

时间:2010-08-06 04:24:57

标签: sql database

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

4 个答案:

答案 0 :(得分:55)

  

内连接的反面是什么?

OUTER联接,可以有三个选项:

  • LEFT
  • RIGHT
  • FULL

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)

答案 1 :(得分: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

答案 2 :(得分:4)

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

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

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)

答案 3 :(得分: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但在地址表中没有相应记录的人。

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