Get recursivly all tree nodes from any node

Viewed 47

I'm looking for the way of how to get all nodes, involved in relations, by specifying any node, e.g. I have the following relations tree, and I whant to get full tree by specifing any of node, let's say by node 4

relations tree

I'm storing this relations in the table of the following format

source value
1 2
1 3
1 4
4 5
5 8
9 19
10 11
1 33

e.t.c

I'm trying to create an SQL query for it, my current version is

     ;WITH CTE AS (
        SELECT val, source, 0 as [Seq]
          FROM [dbo].[Table_1]
          WHERE val = 4 OR source = 4

        UNION ALL
          SELECT rightPath.val, rightPath.source, c.[Seq] - 1 as [Seq]
          FROM [dbo].[Table_1] rightPath
          JOIN CTE c ON rightPath.val = c.source and c.[Seq] <= 0

        UNION ALL
          SELECT leftPath.val, leftPath.source, c.[Seq] + 1 as [Seq]
          FROM [dbo].[Table_1] leftPath
          JOIN CTE c ON leftPath.source = c.val  and c.[Seq] >= 0
      ),CTE2 AS (
        SELECT val, source, 0 as [Seq]  FROM [dbo].[Table_1] WHERE source In (
            SELECT source FROM CTE
        )

        UNION ALL
          SELECT rightPath.val, rightPath.source, c.[Seq] - 1 as [Seq]
          FROM [dbo].[Table_1] rightPath
          JOIN CTE2 c ON rightPath.val = c.source and c.[Seq] <= 0

        UNION ALL
          SELECT leftPath.val, leftPath.source, c.[Seq] + 1 as [Seq]
          FROM [dbo].[Table_1] leftPath
          JOIN CTE2 c ON leftPath.source = c.val  and c.[Seq] >= 0
      )
      SELECT source,val  FROM CTE2 GROUP BY source, val

But as a result I cannot get the following relations (marked red missed relations)

enter image description here

Could you please help me, what I'm missing?

Thanks for any advice!

--------- UPDATE ----------------------

After a few hours, I finally got the expected result, but I'm not sure if it's correct from the SQL best practice point of view. Could you please help me, can this query be improved somehow?

     ;WITH CTE AS (
        SELECT val, source, 0 as [Seq]
          FROM [dbo].[Table_1]
          WHERE val = 4 OR source = 4

        UNION ALL
          SELECT rightPath.val, rightPath.source, c.[Seq] - 1 as [Seq]
          FROM [dbo].[Table_1] rightPath
          JOIN CTE c ON rightPath.val = c.source and c.[Seq] <= 0

        UNION ALL
          SELECT leftPath.val, leftPath.source, c.[Seq] + 1 as [Seq]
          FROM [dbo].[Table_1] leftPath
          JOIN CTE c ON leftPath.source = c.val  and c.[Seq] >= 0
      ), CTE22 AS (
        SELECT val, source, 0 as [Seq]  FROM [dbo].[Table_1] WHERE val In (
            SELECT val FROM CTE
        )

        UNION ALL
          SELECT rightPath.val, rightPath.source, c.[Seq] - 1 as [Seq]
          FROM [dbo].[Table_1] rightPath
          JOIN CTE22 c ON rightPath.val = c.source and c.[Seq] <= 0

        UNION ALL
          SELECT leftPath.val, leftPath.source, c.[Seq] + 1 as [Seq]
          FROM [dbo].[Table_1] leftPath
          JOIN CTE22 c ON leftPath.source = c.val  and c.[Seq] >= 0
      ), CTE33 AS (
        SELECT val, source, 0 as [Seq]  FROM [dbo].[Table_1] WHERE source In (
            SELECT source FROM CTE22
        )

        UNION ALL
          SELECT rightPath.val, rightPath.source, c.[Seq] - 1 as [Seq]
          FROM [dbo].[Table_1] rightPath
          JOIN CTE33 c ON rightPath.val = c.source and c.[Seq] <= 0

        UNION ALL
          SELECT leftPath.val, leftPath.source, c.[Seq] + 1 as [Seq]
          FROM [dbo].[Table_1] leftPath
          JOIN CTE33 c ON leftPath.source = c.val  and c.[Seq] >= 0
      )
      SELECT source,val  FROM CTE33
     GROUP BY source, val
0 Answers
Related