代码之家  ›  专栏  ›  技术社区  ›  fastcodejava

内部连接相反

  •  15
  • fastcodejava  · 技术社区  · 14 年前

    内部连接的相反方向是什么?对于餐桌上的人 (int PersonId, varchar PersoName, int AddrId) ,我想知道与坏 AddrId 这里面没有一排 Address 表。

    4 回复  |  直到 6 年前
        1
  •  55
  •   OMG Ponies    14 年前

    内部连接的相反方向是什么?

    外部联接,可以有三个选项:

    • 正确的

    This is a good visual representation of JOINs

    我想亲自知道地址表中没有坏addrid的行。

    使用左联接/为空

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

    使用不存在

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

    不使用

    SELECT p.*
      FROM PERSON p
     WHERE p.addrid NOT IN (SELECT a.addrid
                              FROM ADDRESS a)
    
        2
  •  7
  •   Thomas    14 年前

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

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

    这将返回表1中的所有行和表2中的任何匹配行,这样,如果给定的表1行没有表2匹配,则返回表2列的空值。然后,通过要求不可为空的列(Table2.PrimaryKeyCol)为空,我将从表1中获取表2中不存在的所有行。使用您的示例表名,我们可以得到如下内容:

    Select ...
    From Person
        Left Join Address
            On Address.PersonId = Person.Id
    Where Address.Id Is Null
    
        3
  •  4
  •   Aaron Silverman    14 年前

    如果将内部联接视为满足特定条件的两个表的行,则相反的情况是 任何一个 没有的桌子。

    例如,下面将选择地址表中具有地址的所有人员:

    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)
    
        4
  •  0
  •   CodeNoob    6 年前

    我认为最好的解决办法是 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: 在中使用常量1 存在 查询以避免表访问。