我有一张像
这样的表格 Users
-------------------------
id | ancestor_id | ....
-------------------------
1 | NULL | ....
2 | 1 | ....
3 | 1 | ....
4 | 3 | ....
5 | 3 | ....
代表像
这样的树 level 1 1
/ \
level 2 2 3
/ \
level 3 4 5
我想创建一个返回给定用户的i
到j
代后代的过程:
CREATE PROCEDURE DescendantsLevel
@user_id INT,
@i INT,
@j INT
AS
....
如果@j
为NULL
,则会返回从代@i
开始的所有后代。
示例:
EXEC DescendantLevel @user_id=1,@i=2,@j=NULL
将返回
-------------------------
id | ancestor_id | ....
-------------------------
1 | NULL | ....
2 | 1 | ....
3 | 1 | ....
4 | 3 | ....
5 | 3 | ....
和
EXEC DescendantLevel @user_id=1,@i=1,@j=2
将返回
Users
-------------------------
id | ancestor_id | ....
-------------------------
1 | NULL | ....
2 | 1 | ....
3 | 1 | ....
我有几个问题:
NULL
更好的价值来代表" infinity"在SQL? 答案 0 :(得分:2)
使用递归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)
这依赖于不超过9999级别的递归(实际上,SQL Server递归的默认限制为100,因此超过100个级别并且您将收到错误)。