Sql 一张桌子的外部与自身连接:这是如何工作的?
我正在阅读《SQL反模式》一书,并试图理解它使用自引用表构建“树”的示例,如Sql 一张桌子的外部与自身连接:这是如何工作的?,sql,database,join,design-patterns,database-design,Sql,Database,Join,Design Patterns,Database Design,我正在阅读《SQL反模式》一书,并试图理解它使用自引用表构建“树”的示例,如 Comments ------------------------------------------------------------------- comment_id | parent_id | author | comment ------------------------------------------------------------
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.
书上说
您可以使用
相对简单的查询:
SELECT c1.*, c2.*
FROM Comments c1 LEFT OUTER JOIN Comments c2
ON c2.parent_id = c1.comment_id
我想知道这是怎么回事。我一直理解表t1
和t2
之间的左外联接的方式是,您从t1
中获取所有的行,对于ON
子句不满意的行,您为第二个表中的列填写NULL
。在本例中,只有一个表,但我可以想象查询是在两个表中进行的,其中第二个表是第一个表的副本。不过,我不明白这个查询是如何返回的
树的两层
结果表到底是什么?您能告诉我结果的逻辑吗?您的理解是正确的-是的,您应该将其视为自身副本的左连接。它表示一个深度级别的原因是,每行表示一条注释,但它可能有一个指向父注释(parent_id)的链接,这意味着您可以将此表转换为树,以帮助直观地理解它。因为你被留下来加入,所以你会接受每一条评论,并将其与所有的子评论进行匹配。如果它没有任何子列,子列将为null(左连接的结果)。如果你画一棵树,你可以把每个节点和它的所有直接子节点圈起来,你会看到这是你的结果集。如果你再次加入,你将进入两个层次的深度,你会得到孩子们的孩子等 编辑:添加了图像(对不起,糟糕的艺术)您应该注意到7个圆圈(原始表格中每行1个)和9个结果行(额外的2个来自注释1和注释4,每个都有2个子项)
生成的表格如下所示:
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\u id=c1.comment\u id
。这意味着“右”表(c2
)的parent.id
将与“左”表(c1
)的comment\u id
连接
该表通过映射每一行及其子注释而分支到自身。右侧(c2
)的结果将是c1
条目的所有子条目,它们对每个子条目重复。由于我们正在进行左连接,因此没有子行的行将在c2
列上返回NULL