SQL Server 中的 LEFT JOIN 与 LEFT OUTER JOIN

Posted

技术标签:

【中文标题】SQL Server 中的 LEFT JOIN 与 LEFT OUTER JOIN【英文标题】:LEFT JOIN vs. LEFT OUTER JOIN in SQL Server 【发布时间】:2010-09-29 05:01:47 【问题描述】:

LEFT JOINLEFT OUTER JOIN 有什么区别?

【问题讨论】:

无! OUTER 关键字是可选的。 维恩图不适合回答这个问题。这个问题的答案是。见第一条评论。 维恩图说明了内连接与外连接特殊情况输出行的差异如果没有输入空值或重复行(因此我们可以将表作为一组行值并使用正常的数学相等)然后左右圆圈保存输出表/集左右连接。但是,如果输入了空值或重复行,那么很难解释这些圆圈是什么集合以及这些集合与输入和输出表/包的关系如何,以至于维恩图没有帮助。 See my comments here re other Venn diagram abuses. 【参考方案1】:

根据文档:FROM (Transact-SQL):

<join_type> ::= 
    [  INNER |   LEFT | RIGHT | FULL  [ OUTER ]   [ <join_hint> ] ]
    JOIN

关键字OUTER 被标记为可选(括在方括号中)。在这种特定情况下,您是否指定OUTER 没有区别。请注意,虽然 join 子句的其他元素也标记为可选,但将 them 排除在外 会有所不同。

例如,JOIN 子句的整个类型部分是可选的,在这种情况下,如果您只指定 JOIN,则默认为 INNER。换句话说,这是合法的:

SELECT *
FROM A JOIN B ON A.X = B.Y

以下是等效语法列表:

A LEFT JOIN B            A LEFT OUTER JOIN B
A RIGHT JOIN B           A RIGHT OUTER JOIN B
A FULL JOIN B            A FULL OUTER JOIN B
A INNER JOIN B           A JOIN B

还可以看看我在另一个 SO 问题上留下的答案:SQL left join vs multiple tables on FROM line?。

【讨论】:

绝对正确。为 ANSI-92 兼容性允许使用 OUTER。 @LasseV.Karlsen 在等价物列表中将INNER JOIN 放在右侧,而将JOIN 放在左侧不是更好吗? @LasseV.Karlsen 我的意思是左边有简洁的形式,右边有扩展的形式。我认为如果你对JOINs 也遵循同样的做法,它会变得连贯。 @Outlier 这是您的特权,但显然还有 451 人认为答案很好。老实说,如果一个答案是 X 而另一个答案是 X 并引用文档,以及将文档的相关部分复制到答案中,我的投票将投给第二个答案,这就是我以这种方式写答案的原因我愿意。有人声称 X 不好。如果你能证明 X,那就更好了(不要轻信sactiw的回答)。但是,想怎么想就怎么想是你的特权。我质疑为什么你认为这是毫无意义的,答案是否有任何错误? @Outlier 老实说,如果您不想阅读我的“长”答案,那么我的答案不适合您。其他人都来这里想知道同样的事情,想了解为什么会这样,以及在哪里可以找到更多信息等。显然你是那种想要这个答案的人:“没有”,但不幸的是这个在 Stack Overflow 上不是一个合法的答案,也不应该是。【参考方案2】:

回答你的问题LEFT JOIN 没有区别 和 LEFT OUTER JOIN,它们完全一样说...

在顶层主要有 3 种连接类型:

    内部 外层 交叉

    INNER JOIN - 如果两个表中都存在数据,则获取数据。

    OUTER JOIN3 种类型:

      LEFT OUTER JOIN - 如果存在于左表中,则获取数据。 RIGHT OUTER JOIN - 如果存在于正确的表中,则获取数据。 FULL OUTER JOIN - 如果存在于两个表中的任何一个中,则获取数据。

    CROSS JOIN,顾名思义,[n X m] 将所有内容连接到所有内容。 类似于我们简单地列出要加入的表的场景(在SELECT 语句的FROM 子句中),使用逗号分隔它们。


注意事项:

如果您只提到JOIN,那么默认情况下它是INNER JOINOUTER 连接必须是 LEFT | RIGHT | FULL 不能简单的说OUTER JOIN。 您可以删除 OUTER 关键字,然后说 LEFT JOINRIGHT JOINFULL JOIN

对于那些想要以更好的方式可视化这些的人,请访问此链接: A Visual Explanation of SQL Joins

【讨论】:

很好的答案。如果您说“LEFT OUTER JOIN - 如果预设,则从左表中获取所有数据并从右表中获取匹配数据”会更清楚。对于 2.1(以及 2.2 的类似更改) 你也可以通过简单的'select * from TableA,TableB'来进行交叉连接 对不起,如果我是 necrobumping,但 CROSS JOIN 是否与 FULL JOIN 相同? @RhysO 不,CROSS JOIN 是笛卡尔积,即 CROSS JOIN 一个表,有 n 行,有一个表,有 m 行,在 FULL OUTER JOIN 时总是给出 (n*m) 行一个有 n 行的表,一个有 m 行的表,将给出最大 (n+m) 行 @sactiw 考虑在您的宝贵答案中添加一个关于Cross JoinFull Outer Join 之间区别的特别说明......在某些方面似乎相似。【参考方案3】:

左连接和左外连接有什么区别?

什么都没有LEFT JOINLEFT OUTER JOIN 是等价的。

【讨论】:

Microsoft SQL Server 和任何其他符合 SQL 的 RDBMS 都是这种情况。 如果您添加一个参考或解释为什么 OUTER 是可选的,那就太好了。 它是可选的,因为它是不必要的! 这里最简洁、准确的答案。 谢谢。接受的答案包含太多信息,让我更加困惑。这正是我需要知道的,并且直截了当地回答了最初的问题。【参考方案4】:

Left JoinLeft Outer Join 是一并且相同。前者是后者的简写。 Right JoinRight Outer Join 的关系也是如此。演示将说明平等。 SQL Fiddle 提供了每个查询的工作示例。该工具将允许手动操作查询。

给定

Left Join 和 Left Outer Join

结果


Right Join 和 Right Outer Join

结果

【讨论】:

【参考方案5】:

我是一名 PostgreSQL DBA,据我所知,外连接与非外连接的区别是一个在互联网上引起广泛讨论的话题。直到今天,我从未看到这两者之间的区别。所以我走得更远,我试图找到它们之间的区别。 最后,我阅读了有关它的整个文档,并找到了答案,

因此,如果您查看文档(至少在 PostgreSQL 中),您会发现这句话:

"The words INNER and OUTER are optional in all forms. INNER is the default; LEFT, RIGHT, and FULL imply an outer join."

换句话说,

LEFT JOINLEFT OUTER JOIN 是一样的

RIGHT JOINRIGHT OUTER JOIN 是一样的

我希望它可以为那些仍在努力寻找答案的人做出贡献。

【讨论】:

【参考方案6】:

我发现按以下顺序考虑联接更容易:

CROSS JOIN - 两个表的笛卡尔积。所有连接都从这里开始 INNER JOIN - 添加了过滤器的 CROSS JOIN。 OUTER JOIN - 缺少元素的 INNER JOIN(来自 LEFT 或 RIGHT 表) 后添加。

在我想出这个(相对)简单的模型之前,JOINS 总是更像是一种黑色艺术。现在它们很有意义。

希望这有助于而不是令人困惑。

【讨论】:

这不能回答问题。【参考方案7】:

为什么 LEFT/RIGHT 和 LEFT OUTER/RIGHT OUTER 相同?让我们解释一下为什么使用这个词汇。 了解 LEFT 和 RIGHT 联接是 OUTER 联接的特定情况,因此只能是 OUTER LEFT/OUTER RIGHT。 OUTER 连接也称为 FULL OUTER,而不是 LEFT 和 RIGHT 连接,它们是 OUTER 连接的 PARTIAL 结果。确实:

Table A | Table B     Table A | Table B      Table A | Table B      Table A | Table B
   1    |   5            1    |   1             1    |   1             1    |   1
   2    |   1            2    |   2             2    |   2             2    |   2
   3    |   6            3    |  null           3    |  null           -    |   -
   4    |   2            4    |  null           4    |  null           -    |   -
                        null  |   5             -    |   -            null  |   5
                        null  |   6             -    |   -            null  |   6

                      OUTER JOIN (FULL)     LEFT OUTER (partial)   RIGHT OUTER (partial)

现在很清楚为什么这些操作有别名,并且很明显只存在 3 种情况:INNER、OUTER、CROSS。 OUTER 有两个子箱。 词汇,老师解释这个的方式,以及上面的一些答案,通常看起来有很多不同类型的连接。但其实很简单。

【讨论】:

“很明显只有 3 个案例存在”:有趣但有缺陷。考虑一个内连接是一个专门的交叉连接(即将连接谓词移动到 where 子句)。进一步考虑外部联接根本不是联接,而是使用空值代替“缺失”列的联合。因此,可以说 cross 是唯一需要的连接。请注意,关系理论中的当前想法是自然连接满足所有连接要求。另外:你能解释一下词汇“JOIN 暗示INNER JOIN”是否/如何符合你对外部连接词汇的推理吗?【参考方案8】:

回答你的问题

在 Sql Server 中加入语法 OUTER 是可选的

在msdn文章中提到:https://msdn.microsoft.com/en-us/library/ms177634(v=sql.130).aspx

所以下面的列表显示了使用和不使用 OUTER

的连接等效语法
LEFT OUTER JOIN => LEFT JOIN
RIGHT OUTER JOIN => RIGHT JOIN
FULL OUTER JOIN => FULL JOIN

其他等效语法

INNER JOIN => JOIN
CROSS JOIN => ,

强烈推荐Dotnet Mob Artice:Joins in Sql Server

【讨论】:

在此处再次滥用维恩图,请参阅我对问题的评论。【参考方案9】:

只有 3 个连接:

A) 交叉连接 = 笛卡尔(例如:表 A、表 B) B) 内部联接 = 联接(例如:表 A 联接/内部联接表 B)

C) 外连接:

   There are three type of outer join
   1)  Left Outer Join     = Left Join
   2)  Right Outer Join    = Right Join
   3)  Full Outer Join     = Full Join    

希望对您有所帮助。

【讨论】:

所以总共有 5 个加入。【参考方案10】:

JOIN主要有3种

    Inner:获取两个表中都存在的数据 只有 JOIN 表示 INNER JOIN

    外:分为三种

    LEFT OUTER - - 获取仅存在于左表和匹配条件中的数据 RIGHT OUTER - - 获取仅存在于右表和匹配条件中的数据 FULL OUTER - - 获取任何或两个表中存在的数据 (LEFT、RIGHT 或 FULL)OUTER JOIN 可以写成不写“OUTER”

    交叉连接:将所有内容连接到所有内容

【讨论】:

【参考方案11】:

语法糖,让不经意的读者更清楚地知道连接不是内部连接。

【讨论】:

那么……那么什么是 FULL OUTER JOIN? tableA FULL OUTER JOIN tableB 将为您提供三种类型的记录:tableA 中的所有记录,tableB 中没有匹配的记录,tableB 中的所有记录,tableA 中没有匹配的记录,tableA 中的所有记录表B中的匹配记录。【参考方案12】:

就这个问题而言,我也想发布 2 个“应用”运算符:

加入

    内部联接 = 联接

    外连接

    左外连接 = 左连接

    右外连接 = 右连接

    完全外连接 = 完全连接

    交叉连接

SELF-JOIN:这不完全是一种单独的连接类型。这基本上是使用上述连接之一将表连接到自身。但我觉得在上下文 JOIN 讨论中值得一提,因为您会从 SQL Developer 社区的许多人那里听到这个术语。

申请

    CROSS APPLY -- 类似于 INNER JOIN(但增加了能够在 Right 表中为 Left 表的每一行计算某些内容并仅返回匹配行的优势) OUTER APPLY -- 类似于 LEFT OUTER JOIN(但增加了能够为左表的每一行计算右表中的某些内容的优势,并且将返回左表中的所有行,而不管右表匹配)

https://www.mssqltips.com/sqlservertip/1958/sql-server-cross-apply-and-outer-apply/

https://sqlhints.com/2016/10/23/outer-apply-in-sql-server/

Real life example, when to use OUTER / CROSS APPLY in SQL

我发现 APPLY 运算符非常有用,因为它们提供了比在子查询中进行相同计算更好的性能。它们还替代了旧版本 SQL Server 中的许多分析函数。这就是为什么我认为在熟悉 JOINS 之后,SQL 开发人员接下来应该尝试学习 APPLY 运算符。

【讨论】:

以上是关于SQL Server 中的 LEFT JOIN 与 LEFT OUTER JOIN的主要内容,如果未能解决你的问题,请参考以下文章

SQL GROUP BY 与 LEFT JOIN MS SQL Server

如何将 LEFT JOIN 限制为 SQL Server 中的第一个结果?

SQL Server:与 TOP 1 的 LEFT OUTER JOIN 最多选择一行

ORACLE LEFT JOIN 子查询 在SQL SERVER中可以使用如图中的子查询,ORACLE中怎么实现

SQL Server 在视图查询中将 LEFT JOIN 替换为 LEFT OUTER JOIN

SQL Server JOINS:SQL Server 中是不是默认关联“JOIN”语句“LEFT OUTER”? [复制]