I have a table that tracks movement of data, it looks like:
From_Id | To_Id |
---|---|
NULL | 1 |
1 | 2 |
NULL | 3 |
3 | 4 |
4 | 5 |
4 | 6 |
5 | 7 |
6 | 10 |
2 | 8 |
8 | 9 |
5 | 9 |
9 | NULL |
10 | NULL |
I want to structure and store every possible paths (e.g 1,2,8,9) and im unsure about the best possible way to do this with SQL.
I started off with a simple while loop, but got a problem at id=4 where it gets 2 new paths. 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:
From_Id | To_Id | path |
---|---|---|
NULL | 1 | 1, |
1 | 2 | 1,2, |
NULL | 3 | 3, |
3 | 4 | 3,4, |
4 | 5 | 3,4,5, |
4 | 6 | 3,4,6, |
5 | 7 | 3,4,5,7, |
6 | 10 | 3,4,6,10, |
2 | 8 | 1,2,8, |
8 | 9 | 1,2,8,9, |
5 | 9 | 3,4,5,9, |
9 | NULL | NULL |
10 | NULL | NULL |
I tried this from How to call a recursive function in sql server
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)
From_Id | To_Id | ID_Path |
---|---|---|
NULL | 1 | 1, |
1 | 2 | 1,2, |
NULL | 3 | 3, |
3 | 4 | 3,4, |
4 | 5 | 3,4,5, |
4 | 6 | 3,4,6, |
5 | 7 | 3,4,5,7, |
6 | 10 | 3,4,6,10 |
2 | 8 | 1,2,8, |
8 | 9 | 1,2,8,9, |
5 | 9 | 3,4,5,9, |
9 | NULL | NULL |
9 | NULL | NULL |
10 | NULL | NULL |