Chr*_*ris 93 sql sql-server recursion self-join hierarchical-data
在SQL Server中执行递归自联接的最简单方法是什么?我有这样一张桌子:
PersonID | Initials | ParentID
1 CJ NULL
2 EB 1
3 MB 1
4 SW 2
5 YT NULL
6 IS 5
Run Code Online (Sandbox Code Playgroud)
而且我希望能够获得仅与特定人员开始的层次结构相关的记录.所以,如果我通过PersonID = 1请求CJ的层次结构,我会得到:
PersonID | Initials | ParentID
1 CJ NULL
2 EB 1
3 MB 1
4 SW 2
Run Code Online (Sandbox Code Playgroud)
对于EB,我会得到:
PersonID | Initials | ParentID
2 EB 1
4 SW 2
Run Code Online (Sandbox Code Playgroud)
我有点卡住这个可以想不出怎么做除了基于一堆连接的固定深度响应.这会发生,因为我们不会有很多级别,但我想做得恰到好处.
谢谢!克里斯.
Qua*_*noi 101
WITH q AS
(
SELECT *
FROM mytable
WHERE ParentID IS NULL -- this condition defines the ultimate ancestors in your chain, change it as appropriate
UNION ALL
SELECT m.*
FROM mytable m
JOIN q
ON m.parentID = q.PersonID
)
SELECT *
FROM q
Run Code Online (Sandbox Code Playgroud)
通过添加排序条件,您可以保留树顺序:
WITH q AS
(
SELECT m.*, CAST(ROW_NUMBER() OVER (ORDER BY m.PersonId) AS VARCHAR(MAX)) COLLATE Latin1_General_BIN AS bc
FROM mytable m
WHERE ParentID IS NULL
UNION ALL
SELECT m.*, q.bc + '.' + CAST(ROW_NUMBER() OVER (PARTITION BY m.ParentID ORDER BY m.PersonID) AS VARCHAR(MAX)) COLLATE Latin1_General_BIN
FROM mytable m
JOIN q
ON m.parentID = q.PersonID
)
SELECT *
FROM q
ORDER BY
bc
Run Code Online (Sandbox Code Playgroud)
通过更改ORDER BY条件,您可以更改兄弟姐妹的顺序.
Adr*_*der 23
使用CTE你可以这样做
DECLARE @Table TABLE(
PersonID INT,
Initials VARCHAR(20),
ParentID INT
)
INSERT INTO @Table SELECT 1,'CJ',NULL
INSERT INTO @Table SELECT 2,'EB',1
INSERT INTO @Table SELECT 3,'MB',1
INSERT INTO @Table SELECT 4,'SW',2
INSERT INTO @Table SELECT 5,'YT',NULL
INSERT INTO @Table SELECT 6,'IS',5
DECLARE @PersonID INT
SELECT @PersonID = 1
;WITH Selects AS (
SELECT *
FROM @Table
WHERE PersonID = @PersonID
UNION ALL
SELECT t.*
FROM @Table t INNER JOIN
Selects s ON t.ParentID = s.PersonID
)
SELECT *
FROm Selects
Run Code Online (Sandbox Code Playgroud)
小智 5
对大表进行了更改的 Quassnoi 查询。孩子多于 10 岁的父母:将 row_number() 格式化为 str(5)
与 q AS
(
SELECT m.*, CAST(str(ROW_NUMBER() OVER (ORDER BY m.ordernum),5) AS VARCHAR(MAX)) COLLATE Latin1_General_BIN AS bc
从#tm
哪里 ParentID =0
联合所有
选择 m.*, q.bc + '.' + str(ROW_NUMBER() OVER (PARTITION BY m.ParentID ORDER BY m.ordernum),5) COLLATE Latin1_General_BIN
从#tm
加入q
ON m.parentID = q.DBID
)
选择 *
从 q
订购者
公元前