【问题标题】:Presentation order of inner self join内自连接的表示顺序
【发布时间】:2013-04-18 20:11:20
【问题描述】:

如果我有如下表:

+------+-------+   
| sno  | cno   |  
+------+-------+  
|    1 | CS112 |  
|    1 | CS113 |  
|    1 | CS114 |  
|    2 | CS112 |  
|    3 | CS112 |  
|    3 | CS114 |  
|    4 | CS112 |  
|    4 | CS113 |  
|    5 | CS113 |  
|    6 | CS113 |  
|    6 | CS114 |  
+------+-------+  

如果我在 sno 上进行内部自联接,我希望看到以下顺序的行:

+------+-------+------+-------+  
| sno  | cno   | sno  | cno   |  
+------+-------+------+-------+  
|    1 | CS112 |    1 | CS112 |  
|    1 | CS112 |    1 | CS113 |  
|    1 | CS112 |    1 | CS114 |  
|    1 | CS113 |    1 | CS112 |  
|    1 | CS113 |    1 | CS113 |  
|    1 | CS113 |    1 | CS114 |  
etc
+------+-------+------+-------+    

但是顺序是

+------+-------+------+-------+  
| sno  | cno   | sno  | cno   |  
+------+-------+------+-------+  
|    1 | CS112 |    1 | CS112 |   
|    1 | CS113 |    1 | CS112 |  
|    1 | CS114 |    1 | CS112 |  
|    1 | CS112 |    1 | CS113 |  
|    1 | CS113 |    1 | CS113 |  
|    1 | CS114 |    1 | CS113 |  
|    1 | CS112 |    1 | CS114 |  
etc
+------+-------+------+-------+    

即我希望看到左侧的每一行都在骑行中的每一行重复。反之亦然。 IE。它似乎需要所有行并将其与连接右侧的第一行匹配。
为什么是这样的顺序?

【问题讨论】:

    标签: mysql sql join self-join


    【解决方案1】:

    除非您使用order by 子句(或在MySQL 中使用group by 子句),否则您不应期望查询中的结果顺序。

    不幸的是,我没有在 MySQL 文档中找到 明确 说明这一点的参考。最接近的是这句话here

    您可能已经注意到,在前面的示例中,结果行 不按特定顺序显示。通常更容易检查 当行以某种有意义的方式排序时查询输出。排序 结果,使用 ORDER BY 子句。

    不过,ANSI 标准确实指定查询结果(和表)是无序的,除非指定了 order by 子句。

    【讨论】:

    • 我明白你的意思,但从概念上讲,我想到的是对左侧表进行线性扫描,并对右侧表进行并行扫描。它似乎反过来做。我想知道为什么。
    • @Cratylus 。 . .在大多数情况下,SQL 是一种描述性 语言。也就是说,它指定了期望的结果,而不是如何获得它们。 SQL 引擎是一个返回这些结果的黑盒。在这种情况下,引擎决定翻转连接的两侧,相对于您的预期。要了解这种和其他优化技术,您需要研究特定数据库的详细信息。
    • 这是我的想法还是大多数教科书没有暗示我所期望的“排序”?
    • @Cratylus 。 . .我不能代表其他作者。我所写的关于 SQL 的所有内容都强调表和查询会产生 无序 结果集。很容易将算法的理解与查询的结果混淆。不幸的是,您不会在 SQL 的介绍性教科书中了解哈希连接、合并连接、并行哈希连接和其他连接技术(并不是说这些在 MySQL 中必须使用)。
    【解决方案2】:

    将表视为记录集。我说“sets”是因为这通常是 SQL 的一个远亲称为Relational Algebra 的有效词。当然,集合中没有顺序。

    添加order by 子句后,您将按指定顺序获得结果:

    select t1.sno, t1.cno, t2.sno, t2.cno from t t1
    join t t2 on t1.sno = t2.sno
    order by t1.sno, t2.sno, t1.cno, t2.cno
    

    【讨论】:

      猜你喜欢
      • 2016-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-06
      • 2017-07-31
      • 2011-04-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多