简体   繁体   English

从 sql 数据库中的结构化表创建树结构

[英]Create a tree structure from a structured table in sql database

I have a table that tracks movement of data, it looks like:我有一个跟踪数据移动的表,它看起来像:

From_Id From_Id To_Id To_Id
NULL NULL 1 1
1 1 2 2
NULL NULL 3 3
3 3 4 4
4 4 5 5
4 4 6 6
5 5 7 7
6 6 10 10
2 2 8 8
8 8 9 9
5 5 9 9
9 9 NULL NULL
10 10 NULL NULL

I want to structure and store every possible paths (eg 1,2,8,9) and im unsure about the best possible way to do this with SQL.我想构造和存储所有可能的路径(例如 1、2、8、9),但我不确定使用 SQL 执行此操作的最佳方法。

I started off with a simple while loop, but got a problem at id=4 where it gets 2 new paths.我从一个简单的 while 循环开始,但在 id=4 处遇到了一个问题,它获得了 2 个新路径。 I tried finding a solution which uses a tree structure, but I couldnt find anything that fits my case.我试图找到一个使用树结构的解决方案,但我找不到任何适合我的情况。

What is a good solution here?这里有什么好的解决方案?

Edit: Im using microsoft sql server desired output:编辑:我使用微软 sql 服务器所需的 output:

From_Id From_Id To_Id To_Id path小路
NULL NULL 1 1 1, 1、
1 1 2 2 1,2, 1,2,
NULL NULL 3 3 3, 3、
3 3 4 4 3,4, 3,4,
4 4 5 5 3,4,5, 3,4,5,
4 4 6 6 3,4,6, 3,4,6,
5 5 7 7 3,4,5,7, 3,4,5,7,
6 6 10 10 3,4,6,10, 3,4,6,10,
2 2 8 8 1,2,8, 1,2,8,
8 8 9 9 1,2,8,9, 1,2,8,9,
5 5 9 9 3,4,5,9, 3,4,5,9,
9 9 NULL NULL NULL NULL
10 10 NULL NULL NULL NULL

I tried this from How to call a recursive function in sql server我从如何在 sql 服务器中调用递归 function尝试了这个

DECLARE @TABLE2 TABLE(
    From_Id INT,
    To_id INT
)

INSERT INTO @TABLE2 SELECT NULL,1
INSERT INTO @TABLE2 SELECT 1,2
INSERT INTO @TABLE2 SELECT NULL,3
INSERT INTO @TABLE2 SELECT 3,4
INSERT INTO @TABLE2 SELECT 4,5
INSERT INTO @TABLE2 SELECT 4,6
INSERT INTO @TABLE2 SELECT 5,7
INSERT INTO @TABLE2 SELECT 6,10
INSERT INTO @TABLE2 SELECT 2,8
INSERT INTO @TABLE2 SELECT 8,9
INSERT INTO @TABLE2 SELECT 5,9
INSERT INTO @TABLE2 SELECT 9,NULL
INSERT INTO @TABLE2 SELECT 10,NULL

;WITH Recursives AS (
        SELECT  *,
                CAST(To_id AS VARCHAR(MAX)) + ',' ID_Path
        FROM    @TABLE2
        WHERE   From_Id IS NULL
        UNION ALL
        SELECT  t.*,
        r.ID_Path + CAST(t.To_id AS VARCHAR(MAX)) + ','
        FROM    @TABLE2 t INNER JOIN
                Recursives r ON t.From_Id = r.To_id
)

SELECT  *
FROM Recursives

Which gave me an extra row (it gets much larger when i have 10k + rows)这给了我一个额外的行(当我有 10k + 行时它变得更大)

From_Id From_Id To_Id To_Id ID_Path ID_路径
NULL NULL 1 1 1, 1、
1 1 2 2 1,2, 1,2,
NULL NULL 3 3 3, 3、
3 3 4 4 3,4, 3,4,
4 4 5 5 3,4,5, 3,4,5,
4 4 6 6 3,4,6, 3,4,6,
5 5 7 7 3,4,5,7, 3,4,5,7,
6 6 10 10 3,4,6,10 3,4,6,10
2 2 8 8 1,2,8, 1,2,8,
8 8 9 9 1,2,8,9, 1,2,8,9,
5 5 9 9 3,4,5,9, 3,4,5,9,
9 9 NULL NULL NULL NULL
9 9 NULL NULL NULL NULL
10 10 NULL NULL NULL NULL

Create a many-to-many relationship.创建多对多关系。 A new table will be created that will only store id pairs if they exist.将创建一个仅存储 id 对(如果存在)的新表。 In the case of id 4, 2 separate records will be created.在 id 4 的情况下,将创建 2 个单独的记录。 Of course, if you want to display records from a new array, you can also use the select command.当然,如果要显示新数组中的记录,也可以使用 select 命令。

The problem arises if the From_Id and To_Id fields come from the same table.如果 From_Id 和 To_Id 字段来自同一个表,就会出现问题。 In this case, an intermediate table should be created.在这种情况下,应该创建一个中间表。 I will use a simple one here.我将在这里使用一个简单的。

An example of a social networking site.一个社交网站的例子。 We have a user tracking feature.我们有一个用户跟踪功能。 In this way, we create 2 instances of the follower of the user and observe.这样,我们创建了2个用户的follower实例并进行观察。 We cannot create a direct mana-to-many relationship because this cannot directly refer to the same table.我们不能创建直接的mana-to-many 关系,因为这不能直接引用同一张表。 We create 2 additional tables.我们创建了 2 个额外的表。 One will save users as followers and the other as followed.一个会将用户保存为关注者,另一个将保存为关注者。 It is between these tables that we create a many-to-many relationship.正是在这些表之间,我们创建了多对多关系。

图形示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM