[英]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.