sql-什么时候或为什么要使用右外部联接而不是左联接?

维基百科指出:

“实际上,很少使用显式的右外部联接,因为它们总是可以用左外部联接替换,并且不提供任何其他功能。”

任何人都可以提供他们偏爱使用RIGHT符号的情况,为什么?我想不出使用它的理由。 对我来说,这永远不会使事情变得更清楚。

编辑:我是一位Oracle资深人士,正在制定“新年决议”以使自己摆脱(+)语法。 我想做对

DCookie asked 2020-01-13T15:15:54Z
11个解决方案
35 votes

我能想到使用RIGHT OUTER JOIN的唯一原因是试图使您的SQL更具自记录性。

对于在一对多关系的从属关系(许多)中具有空行的查询,您可能需要使用左联接,而在独立关系中产生空行的那些查询中,则可以使用左连接。

这也可能发生在生成的代码中,或者如果商店的编码要求在FROM子句中指定了表的声明顺序。

Yes - that Jake. answered 2020-01-13T15:16:12Z
16 votes

我以前从未使用过left join,也从未想到自己实际上会需要它,这似乎有点不自然。 但是经过考虑之后,在需要将一个表与多个表的交集进行外部联接的情况下,它可能会非常有用,因此您拥有这样的表:

enter image description here

并希望得到这样的结果:

enter image description here

或者,在SQL中(MS SQL Server):

declare @temp_a table (id int)
declare @temp_b table (id int)
declare @temp_c table (id int)
declare @temp_d table (id int)

insert into @temp_a
select 1 union all
select 2 union all
select 3 union all
select 4

insert into @temp_b
select 2 union all
select 3 union all
select 5

insert into @temp_c
select 1 union all
select 2 union all
select 4

insert into @temp_d
select id from @temp_a
union
select id from @temp_b
union
select id from @temp_c

select *
from @temp_a as a
    inner join @temp_b as b on b.id = a.id
    inner join @temp_c as c on c.id = a.id
    right outer join @temp_d as d on d.id = a.id

id          id          id          id
----------- ----------- ----------- -----------
NULL        NULL        NULL        1
2           2           2           2
NULL        NULL        NULL        3
NULL        NULL        NULL        4
NULL        NULL        NULL        5

因此,如果切换到left join,结果将不会相同。

select *
from @temp_d as d
    left outer join @temp_a as a on a.id = d.id
    left outer join @temp_b as b on b.id = d.id
    left outer join @temp_c as c on c.id = d.id

id          id          id          id
----------- ----------- ----------- -----------
1           1           NULL        1
2           2           2           2
3           3           3           NULL
4           4           NULL        4
5           NULL        5           NULL

没有正确连接的唯一方法是使用公用表表达式或子查询

select *
from @temp_d as d
    left outer join (
        select *
        from @temp_a as a
            inner join @temp_b as b on b.id = a.id
            inner join @temp_c as c on c.id = a.id
    ) as q on ...
Roman Pekar answered 2020-01-13T15:16:51Z
15 votes

B右联接A与A左联接B相同

B右联接A读取:B右,然后联接A。表示A在数据集的左侧。 和A LEFT JOIN B一样

如果将LEFT JOIN重新排列为RIGHT,将无法获得任何性能。

我能想到为什么要使用RIGHT JOIN的唯一原因是,如果您是喜欢从内而外思考的人(从详细的right join header中选择*)。 就像其他人喜欢小端,其他人喜欢大端,其他人喜欢自上而下的设计,其他人喜欢自下而上的设计。

另一个是如果您已经有一个庞大的查询要在其中添加另一个表,那么在重新安排查询时会很麻烦,因此只需使用RIGHT JOIN将表插入现有查询即可。

Michael Buen answered 2020-01-13T15:17:29Z
8 votes

我唯一想到的是正确的外部联接,如果我要固定完全联接,那恰好是我需要结果包含右侧表中的所有记录。 但是,即使像我一样懒惰,我也可能会非常恼火,以至于我会重新排列它以使用左联接。

维基百科的这个例子显示了我的意思:

SELECT *  
FROM   employee 
   FULL OUTER JOIN department 
      ON employee.DepartmentID = department.DepartmentID

如果仅将单词FULL替换为RIGHT,您将有一个新查询,而不必交换ON子句的顺序。

Bill the Lizard answered 2020-01-13T15:17:58Z
3 votes
SELECT * FROM table1 [BLANK] OUTER JOIN table2 ON table1.col = table2.col

将[空白]替换为:

左-如果您想要来自table1的所有记录,即使它们没有与table2匹配的列(也包括具有匹配项的table2记录)

正确-如果您想要来自table2的所有记录,即使它们没有与table1匹配的列(也包括具有匹配项的table1记录)

FULL-如果要从table1和table2获得所有记录

大家都在说什么 他们是一样的吗? 我不这么认为。

Andrew G. Johnson answered 2020-01-13T15:18:36Z
3 votes
SELECT * FROM table_a
INNER JOIN table_b ON ....
RIGHT JOIN table_c ON ....

在确保始终选择table_c中的所有行的同时,如何还能快速/轻松地内部联接前2个表并与table_c联接?

Matt answered 2020-01-13T15:18:57Z
2 votes

SQL语句除了正确之外,还应尽可能易于阅读和表达简洁(因为它们代表单个原子动作,并且您的思维需要完全停顿它们,以避免意外的后果。)有时,用 正确的外部联接。

但是总是可以将其中一个转换为另一个,并且优化程序对另一个也可以做到。

相当长一段时间以来,至少一种主要的rdbms产品仅支持LEFT OUTER JOIN。 (我相信是MySQL。)

dkretz answered 2020-01-13T15:19:26Z
2 votes

只有当我想查看两组数据时,才使用右连接,而对于先前编写的查询中的左连接或内部连接,我已经按特定顺序进行了连接。 在这种情况下,假设您希望将未包含在表a中但在表b中的记录视为一组数据,而将另一组中的记录不在表b中,而是在表a中。 即使那样,我还是倾向于这样做,以节省进行研究的时间,但是如果代码要运行多次,它将改变它。

HLGEM answered 2020-01-13T15:19:48Z
2 votes

我实际上并不需要为正确的联接考虑太多,但是我想我在编写SQL查询的近20年中没有遇到使用它的合理理由。 我当然已经看过很多,我猜它们可能是由于开发人员在哪里使用内置查询构建器而引起的。

每当遇到一个查询时,我都会重写该查询以消除该查询-如果您已经有一段时间没有访问该查询了,那么他们只是需要太多额外的精力来学习或重新学习,而没有 查询丢失或返回错误结果的意图并不少见-通常是这种错误导致我要求检查查询为什么不起作用。

考虑一下,一旦引入了右联接,您现在就拥有了我认为需要在中间满足的竞争性逻辑分支。 如果引入了其他要求/条件,则可能会进一步扩展这两个分支,并且您现在已经变得更加复杂,必须努力确保一个分支不会引起错误的结果。

此外,一旦您引入了正确的联接,其他稍后在查询中工作的经验不足的开发人员可能会简单地将附加表附加到查询的正确联接部分,从而扩展仍然需要满足的竞争逻辑流程。 中间; 或在某些情况下,我开始嵌套视图是因为它们不想触及原始逻辑,也许部分是因为它们可能不了解驱动逻辑的查询或业务规则。

mattpm answered 2020-01-13T15:20:24Z
1 votes

在某些SQL数据库中,存在优化程序提示,告诉优化程序按照表在FROM子句中出现的顺序连接表-例如 Oracle中的FROM。 在某些简单的实现中,这甚至可能是唯一可用的执行计划。

在这种情况下,FROM子句中的表顺序很重要,因此RIGHT JOIN可能有用。

Jiri Tousek answered 2020-01-13T15:20:49Z
0 votes

我认为在这种情况下如果您没有正确的加入很难。 前与甲骨文。

with a as(
     select 1 id, 'a' name from dual union all
     select 2 id, 'b' name from dual union all
     select 3 id, 'c' name from dual union all
     select 4 id, 'd' name from dual union all
     select 5 id, 'e' name from dual union all
     select 6 id, 'f' name from dual 
), bx as(
   select 1 id, 'fa' f from dual union all
   select 3 id, 'fb' f from dual union all
   select 6 id, 'f' f from dual union all
   select 6 id, 'fc' f from dual 
)
select a.*, b.f, x.f
from a left join bx b on a.id = b.id
right join bx x on a.id = x.id
order by a.id
Hong Van Vit answered 2020-01-13T15:21:09Z
translate from https://stackoverflow.com:/questions/436345/when-or-why-would-you-use-a-right-outer-join-instead-of-left