I have a table like
Users
-------------------------
id | ancestor_id | ....
-------------------------
1 | NULL | ....
2 | 1 | ....
3 | 1 | ....
4 | 3 | ....
5 | 3 | ....
that would represent a tree like
level 1 1
/ \
level 2 2 3
/ \
level 3 4 5
and I want to create a procedure that returns the i
th through j
th generation of descendants of a given user:
CREATE PROCEDURE DescendantsLevel
@user_id INT,
@i INT,
@j INT
AS
....
If @j
is NULL
, however, it returns all descendants beginning from generation @i
.
Examples:
EXEC DescendantLevel @user_id=1,@i=2,@j=NULL
would return
-------------------------
id | ancestor_id | ....
-------------------------
1 | NULL | ....
2 | 1 | ....
3 | 1 | ....
4 | 3 | ....
5 | 3 | ....
and
EXEC DescendantLevel @user_id=1,@i=1,@j=2
would return
Users
-------------------------
id | ancestor_id | ....
-------------------------
1 | NULL | ....
2 | 1 | ....
3 | 1 | ....
Several questions, I have:
NULL
to represent some concept of "infinity" in SQL? Using a recursive CTE:
DECLARE @test TABLE (id INT NOT NULL, ancestor_id INT NULL)
DECLARE
@id INT = 1,
@i INT = 1,
@j INT = 2
INSERT INTO @test (id, ancestor_id)
VALUES
(1, NULL),
(2, 1),
(3, 1),
(4, 3),
(5, 3)
;WITH CTE_Tree AS
(
SELECT
id,
ancestor_id,
1 AS lvl,
id AS base
FROM
@test
WHERE
id = @id
UNION ALL
SELECT
C.id,
C.ancestor_id,
P.lvl + 1 AS lvl,
P.base AS base
FROM
CTE_Tree P
INNER JOIN @test C ON C.ancestor_id = P.id
WHERE
lvl <= COALESCE(@j, 9999)
)
SELECT
id,
ancestor_id
FROM
CTE_Tree
WHERE
lvl BETWEEN @i AND COALESCE(@j, 9999)
This relies on no more than 9999 levels of recursion (actually the default limit on recursion for SQL Server is 100, so more than 100 levels and you'll get an error).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With