SQL左连接a和b -> b右连接a:顺序的差异

3

我有时读到写“a left join b”和“b right join a”是等价的。我以为我能理解这一点,但是我在一本书中读到这不是这样的。它说结果元组是相同的,但它们可能是按不同顺序排列的。我找不到对此的解释。我也尝试在我的本地MySQL服务器上重现这种顺序差异,但我无法做到。 唯一的区别似乎是属性的顺序。 有人可以向我解释何时或为什么会出现元组顺序的差异吗?


1
请引用书中的确切句子。如果没有“ORDER BY”子句,那么查询结果的顺序是不确定的,这适用于几乎所有的查询。 - undefined
这是一本德语书。它说如果你在右连接中同时更改两个表,并使用左连接代替,返回的元组将是相同的,但可能会有不同的顺序。我认为Gerard H. Pille对这个问题回答得很好。 - undefined
我不同意这个观点。至少在MySQL中,右连接被简化为左连接(参考链接),所以b right join a在幕后被视为a left join b。但是是的,只要没有使用ORDER BY语句,服务器可以以任何顺序返回行。 - undefined
这本书是德文的,难道这不是它质量的保证吗?;-) 我发现了解关系理论对于我们这些普通程序员来说非常有益。这本书是必读的:https://www.goodreads.com/book/show/6219481-sql-and-relational-theory - undefined
关系体是元组的集合,没有顺序。也没有标准的特殊关系值NULL,但可以定义外连接来引入任意给定的值以扩展未匹配的输入元组。SQL表也是无序的;如果使用ORDER BY,则“结果集”(查询结果)是有序的,否则不保证有序--所以“可能有不同的顺序”。SQL左连接和右连接以不同的顺序返回列。在关系上,列是否有序以及连接如何对它们排序取决于所使用代数的细节。请引用并参考该书。 - undefined
显示剩余2条评论
2个回答

5

这比听起来要复杂得多。首先:

select *
from a left join b on . . . ;

并且:

select *
from b right join a on . . . ;

可能会产生两种不同的结果集:
  • 列的顺序不同。
  • 行可能以不同的顺序出现。
从集合论的角度来看,这些都不会影响结果集的等价性。但是它们可能会产生实际效果。一般来说,如果您关心顺序,那么分别:
  • 显式列出列。
  • 包括一个 order by
更重要的是,在存在多个连接时,left joinright join 不能互换,因为连接始终从左到右关联,而与类型无关。
在下面的示例中,我省略了 on 子句。请考虑:
from a left join b left join c

你可能认为与右连接等效的是:

from c right join b right join a

但是,这些join被分组了,因此第一个被解释为:
from (a left join b) left join c

第二点是:
from (c right join b) right join a

但使用 right join 的等效语句是:

from c right join (b right join a)

在这两种情况下,a 中的每一行都将出现在结果集中。但是根据三个表之间的重叠情况,结果可能会有所不同。

2

我有时会看到一些文章说,元组返回的顺序并不重要。实际数据库返回记录的顺序可能会发生变化,因为引擎决定使用索引或不使用索引找到更好的路径,或者因为数据块已经移动等等。关系理论和您选择的数据库之间存在很大差异。这并不是指MySQL。


关系体是元组的集合,没有顺序。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接