Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 一张桌子的外部与自身连接:这是如何工作的?_Sql_Database_Join_Design Patterns_Database Design - Fatal编程技术网

Sql 一张桌子的外部与自身连接:这是如何工作的?

Sql 一张桌子的外部与自身连接:这是如何工作的?,sql,database,join,design-patterns,database-design,Sql,Database,Join,Design Patterns,Database Design,我正在阅读《SQL反模式》一书,并试图理解它使用自引用表构建“树”的示例,如 Comments ------------------------------------------------------------------- comment_id | parent_id | author | comment ------------------------------------------------------------

我正在阅读《SQL反模式》一书,并试图理解它使用自引用表构建“树”的示例,如

                         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