【问题标题】:Does anyone use Right Outer Joins?有人使用右外连接吗?
【发布时间】:2010-10-15 22:53:39
【问题描述】:

我一直使用 INNER JOIN 和 LEFT OUTER JOIN。但是,我似乎从来不需要 RIGHT OUTER JOIN。

我见过很多使用右连接的讨厌的自动生成的 SQL,但对我来说,这些代码是不可能让我理解的。我总是需要使用内连接和左连接来重写它来制作它的头部或尾部。

真的有人使用右连接编写查询吗?

【问题讨论】:

标签: sql


【解决方案1】:

举一个RIGHT JOIN可能有用的例子。

假设有三个表格,分别代表人物、宠物和宠物配饰。人们可以选择养宠物,这些宠物也可以选择拥有配饰

CREATE TABLE Persons
  (
     PersonName VARCHAR(10) PRIMARY KEY
  );

INSERT INTO Persons
VALUES      ('Alice'),
            ('Bob'),
            ('Charles');

CREATE TABLE Pets
  (
     PetName    VARCHAR(10) PRIMARY KEY,
     PersonName VARCHAR(10)
  );

INSERT INTO Pets
VALUES      ('Rover',
             'Alice'),
            ('Lassie',
             'Alice'),
            ('Fifi',
             'Charles');

CREATE TABLE PetAccessories
  (
     AccessoryName VARCHAR(10) PRIMARY KEY,
     PetName       VARCHAR(10)
  );

INSERT INTO PetAccessories
VALUES      ('Ball', 'Rover'),
            ('Bone', 'Rover'),
            ('Mouse','Fifi');

如果要求获得列出所有人的结果,无论他们是否拥有宠物,以及有关他们拥有的任何宠物的信息。

不起作用(不包括 Bob)

SELECT P.PersonName,
       Pt.PetName,
       Pa.AccessoryName
FROM   Persons P
       LEFT JOIN Pets Pt
         ON P.PersonName = Pt.PersonName
       INNER JOIN PetAccessories Pa
         ON Pt.PetName = Pa.PetName; 

不起作用(包括 Lassie)

SELECT P.PersonName,
       Pt.PetName,
       Pa.AccessoryName
FROM   Persons P
       LEFT JOIN Pets Pt
         ON P.PersonName = Pt.PersonName
       LEFT JOIN PetAccessories Pa
         ON Pt.PetName = Pa.PetName; 

确实有效(但语法不太常见,因为它需要两个连续的ON 子句才能实现所需的逻辑连接顺序)

SELECT P.PersonName,
       Pt.PetName,
       Pa.AccessoryName
FROM   Persons P
       LEFT JOIN Pets Pt
                  INNER JOIN PetAccessories Pa
                    ON Pt.PetName = Pa.PetName
         ON P.PersonName = Pt.PersonName;

总而言之,RIGHT JOIN 可能最容易使用

SELECT P.PersonName,
       Pt.PetName,
       Pa.AccessoryName
FROM   Pets Pt
       JOIN PetAccessories Pa
         ON Pt.PetName = Pa.PetName
       RIGHT JOIN Persons P
         ON P.PersonName = Pt.PersonName;

如果确定要避免这种情况,另一种选择是引入一个可以左连接的派生表

SELECT P.PersonName,
       T.PetName,
       T.AccessoryName
FROM   Persons P
       LEFT JOIN (SELECT Pt.PetName,
                         Pa.AccessoryName,
                         Pt.PersonName
                  FROM   Pets Pt
                         JOIN PetAccessories Pa
                           ON Pt.PetName = Pa.PetName) T
         ON T.PersonName = P.PersonName; 

SQL 小提琴:MySQLPostgreSQLSQL Server

【讨论】:

  • 如果你不明白为什么可怜的 Bob 被排除在外,这对我有帮助:weblogs.sqlteam.com/jeffs/archive/2007/10/11/…
  • @Luke - 巧合的是我们都用了一个“宠物”的例子!
  • 在链接两个以上的表时,在某些情况下使用右连接可能确实会产生更好的查询。但是我想,对于许多人来说,编写一个更复杂的 LEFT 查询仍然会更容易,因为习惯于从主数据集开始,然后附加“子”数据。
  • 这是 RIGHT JOIN 的罕见用例的一个很好的例子,但仍然:您可以通过将要求添加为 WHERE 条件来使用 LEFT JOIN 获得相同的结果(不包括“Lassie”),即WHERE PetAcessories.ID IS NOT NULL。执行计划将是相同的,并且查询的意图更具可读性。
【解决方案2】:

我只使用 left,但我想说它们实际上是相同的,具体取决于您如何订购。我与一些只使用正确的人一起工作,因为他们从内到外构建查询并且喜欢将主要项目保留在底部,因此在他们看来,只使用正确是有意义的。

这里有重点

需要更多垃圾

More Junk right outer join Main Stuff

我更喜欢做主要的事情而不是垃圾......所以我只剩下外部工作了。

所以不管你的船是什么。

【讨论】:

    【解决方案3】:

    很少,如前所述,您通常可以重新排序并使用左连接。此外,我自然倾向于对数据进行排序,这样左连接就可以获取我需要的数据。我认为完全外部连接和交叉连接也是如此,大多数人倾向于远离它们。

    【讨论】:

      【解决方案4】:

      您可以使用 LEFT 或 RIGHT 连接来完成同样的事情。一般来说,大多数人认为左连接可能是因为我们从左到右阅读。这真的归结为保持一致。您的团队应该专注于使用 LEFT 或 RIGHT 连接,而不是两者,因为它们本质上是完全相同的东西,但写法不同。

      【讨论】:

        【解决方案5】:

        我唯一一次使用右外连接是在我处理现有查询并需要更改它(通常从内部)时。我可以反转连接并使其左转并且可能没问题,但是我尝试减少修改代码时更改的内容的数量。

        【讨论】:

          【解决方案6】:

          这取决于您将每个表放在联接的哪一侧。

          如果你想返回左表中的所有行,即使右表中没有匹配项......你使用左连接。

          如果要返回右表中的所有行,即使左表中没有匹配项,也可以使用右连接。

          有趣的是,我很少使用右连接。

          【讨论】:

          • 我总是发现从包含所有非孤立项的表开始更合乎逻辑,所以我也总是最终使用 LEFT JOIN。我想知道这是不是一种文化?
          • +1,左右外连接完全相同,只是相反。
          • @MatthieuF:也许是文化问题。使用右连接感觉就像以相反的方式做某事。至少在我看来,它总是以某种方式安排我的加入,以便(如果需要)左加入适合这种情况。我不知道为什么? :-)
          • MySQL 建议使用 LEFT JOIN 来实现跨数据库的代码可移植性。在dev.mysql.com/doc/refman/5.0/en/join.html 上查看他们关于 RIGHT JOIN 的部分
          • 根据sqlitetutorial.net/sqlite-full-outer-join具体Sqllite只实现LEFT JOIN而不是RIGHT(或FULL)
          【解决方案7】:

          我们这里的标准做法是尽可能使用 LEFT JOIN 来编写所有内容。如果需要,我们偶尔会使用 FULL OUTER JOIN,但从不使用 RIGHT JOIN。

          【讨论】:

            【解决方案8】:

            您通常使用 RIGHT OUTER JOINS 在其他表中查找孤立项。

            【讨论】:

            • 你能提供更多细节吗?
            • 我发现这个答案让正确的连接听起来很特别,但实际上它们不是。左外连接和右外连接是彼此的镜像 - 两者都可用于查找孤立项。使用哪个表的选择只是基于您希望所有行来自哪个表,即使没有匹配项。
            【解决方案9】:

            不,我不这样做的原因很简单,我可以使用内连接或左连接来完成所有事情。

            【讨论】:

              猜你喜欢
              • 2018-01-08
              • 2014-02-24
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-09-15
              • 1970-01-01
              • 1970-01-01
              • 2015-01-11
              相关资源
              最近更新 更多