一张桌子左外连接自己:这是如何工作的?

时间:2015-12-27 07:42:35

标签: sql database join design-patterns database-design

我正在阅读 SQL Antipatterns 这本书,并试图理解它构建一个&#34树"的例子。使用自引用表,如

                         Comments
-------------------------------------------------------------------
  comment_id | parent_id | author |      comment
-------------------------------------------------------------------
       1          NULL     Fran      What's the cause of this bug?
       2            1      Ollie     I think it's a null pointer.
       3            2      Fran      No, I checked for that.
       4            1      Kukla     We need to check for invalid input.
       5            4      Ollie     Yes, that's a bug.
       6            4      Fran      Yes, please add a check.
       7            6      Kukla     That fixed it.

所以书上写着

  

您可以使用a来检索评论及其直接孩子   相对简单的查询:

SELECT c1.*, c2.*
FROM Comments c1 LEFT OUTER JOIN Comments c2
  ON c2.parent_id = c1.comment_id

我试图了解这是如何运作的。我总是理解表t1t2之间的外部联接的方式是,您从t1获取所有行以及行如果不满足ON子句,则为第二个表中的列填写NULL。在这种情况下,只有一个表,但我可以想象查询是在两个表中进行的,其中第二个是第一个表的副本。不过,我不明白该查询是如何返回的

  

树的两个层次。

结果表到底是什么,你能指导我了解它的结果吗?

2 个答案:

答案 0 :(得分:2)

您的理解是正确的 - 是的,您应该将其视为对自身副本的左连接。它表示一个深度级别的原因是因为每一行代表一个注释,但它可能有一个指向父注释(parent_id)的链接,这意味着您可以将此表转换为树以帮助在视觉上理解它。因为您正在加入,所以您将收集每条评论并将其与其所有孩子进行匹配。如果它没有任何子节点,子列将为空(左连接的结果)。如果你画出一棵树,你可以拿出每个节点并圈出它以及它所有直接的孩子,你会看到那是你的结果集。如果你再次加入,你会深入2级,你会得到孩子们的孩子等。

编辑:添加图片(对不起艺术品)您应该注意到7个圆圈(原始表格中每行1个)和9个结果行(额外2个来自评论1和4,每个有2个孩子)

7 circles, 9 resulting rows

答案 1 :(得分:2)

结果表如下:

http://www.parentwebsite.com/one.php?id=http://www.child.com/

Comments ------------------------------------------------------------------------------------------------------------------------------------------------------------------- c1.comment_id | c1.parent_id | c1.author | c1.comment | c2.comment_id | c2.parent_id | c2.author | c2.comment | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 NULL Fran What's the cause of this bug? 2 1 Ollie I think it's a null pointer. 1 NULL Fran What's the cause of this bug? 4 1 Kukla We need to check for invalid input. 2 1 Ollie I think it's a null pointer. 3 2 Fran No, I checked for that. 3 2 Fran No, I checked for that. NULL NULL NULL NULL 4 1 Kukla We need to check for invalid input. 5 4 Ollie Yes, that's a bug. 4 1 Kukla We need to check for invalid input. 6 4 Fran Yes, please add a check. 5 4 Ollie Yes, that's a bug. NULL NULL NULL NULL 6 4 Fran Yes, please add a check. 7 6 Kukla That fixed it. 7 6 Kukla That fixed it. NULL NULL NULL NULL 子句中,我们有ON。这意味着“正确”表格c2.parent_id = c1.comment_id)的c2将与“左”表(parent.id)的c1一起加入。

该表通过映射每一行及其子注释来分支到自身。右侧(comment_id)的结果将是c2条目的所有子项,每个子项重复一次。由于我们正在进行左连接,因此没有子项的行只会在c1列上返回NULL

相关问题