我正在阅读 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
我试图了解这是如何运作的。我总是理解表t1
和t2
之间的外部联接的方式是,您从t1
获取所有行以及行如果不满足ON
子句,则为第二个表中的列填写NULL
。在这种情况下,只有一个表,但我可以想象查询是在两个表中进行的,其中第二个是第一个表的副本。不过,我不明白该查询是如何返回的
树的两个层次。
结果表到底是什么,你能指导我了解它的结果吗?
答案 0 :(得分:2)
您的理解是正确的 - 是的,您应该将其视为对自身副本的左连接。它表示一个深度级别的原因是因为每一行代表一个注释,但它可能有一个指向父注释(parent_id)的链接,这意味着您可以将此表转换为树以帮助在视觉上理解它。因为您正在加入,所以您将收集每条评论并将其与其所有孩子进行匹配。如果它没有任何子节点,子列将为空(左连接的结果)。如果你画出一棵树,你可以拿出每个节点并圈出它以及它所有直接的孩子,你会看到那是你的结果集。如果你再次加入,你会深入2级,你会得到孩子们的孩子等。
编辑:添加图片(对不起艺术品)您应该注意到7个圆圈(原始表格中每行1个)和9个结果行(额外2个来自评论1和4,每个有2个孩子)
答案 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
。