递归查询 - PARENT/CHILD
RECURSIVE QUERY - PARENT/CHILD
假设我有一个 table 像这样:
id Parentid childid
--------------------------------
01 null 02
02 01 03
03 02 04
04 03 06
05 051 101
06 04 055
假设我总是得到一个中间值,这样一个节点同时具有 children 和 parent 节点,此时我不知道它们是什么。例如,我得到了 ID:4。我写了一个递归查询,它让我同时获得 Parents 和 child 记录,但我很不确定它是否是正确的方法,但如果它是最快的。
with x as (
--These are the anchor (the parents)
select *
from table with (nolock)
where id= 04
),
parents as (
SELECT *
FROM x
UNION ALL
SELECT p.*
FROM parents JOIN
table p
ON parents.ID = p.childid
),
children as (
SELECT top 1 *
FROM x
UNION ALL
SELECT p.*
FROM children JOIN
table p
parents.id = p.parentid
)
SELECT distinct *
FROM parents
UNION
SELECT distinct *
FROM children;
这是我希望结果返回的方式,所以 return id: 01,02,03,04,06 因为它们是 parent 或 child ID 04等
基本上我希望得到的是什么是进行递归查询以获取给定记录的 parent 和 child 的最佳方法,在哪里可以找到 children 你必须使用 1 列并且要获得 parents 必须使用另一列等等
这是伪 SQL 条款,但您只需要 2 个 CTE,无需 DISTINCT
即可获得您想要的结果。遍历分层数据,不使用 hierachyid
数据类型永远不会像它可能的那样有效,因为您需要递归。
无论如何,你实际上只想要这个:
USE Sandbox;
GO
CREATE TABLE dbo.YourTable (ID int, ParentID int);
INSERT INTO dbo.YourTable (ID,
ParentID)
VALUES(1,NULL),
(2,NULL),
(3,1),
(4,1),
(5,2),
(6,3),
(7,4),
(8,4),
(9,7),
(10,8);
GO
DECLARE @ID int = 4;
WITH Parents AS(
SELECT YT.ID,
YT.ParentID
FROM dbo.YourTable YT
WHERE YT.ID = @ID
UNION ALL
SELECT YT.ID,
YT.ParentID
FROM Parents P
JOIN dbo.YourTable YT ON P.ParentID = YT.ID),
Children AS(
SELECT YT.ID,
YT.ParentID
FROM dbo.YourTable YT
WHERE YT.ID = @ID
UNION ALL
SELECT YT.ID,
YT.ParentID
FROM Children C
JOIN dbo.YourTable YT ON C.ID = YT.ParentID)
SELECT ID, ParentID
FROM Parents P
UNION ALL
SELECT ID, ParentID
FROM Children C
WHERE C.ID != @ID --Stops the initial row being displayed twice
ORDER BY ID ASC;
GO
DROP TABLE dbo.YourTable;
假设我有一个 table 像这样:
id Parentid childid
--------------------------------
01 null 02
02 01 03
03 02 04
04 03 06
05 051 101
06 04 055
假设我总是得到一个中间值,这样一个节点同时具有 children 和 parent 节点,此时我不知道它们是什么。例如,我得到了 ID:4。我写了一个递归查询,它让我同时获得 Parents 和 child 记录,但我很不确定它是否是正确的方法,但如果它是最快的。
with x as (
--These are the anchor (the parents)
select *
from table with (nolock)
where id= 04
),
parents as (
SELECT *
FROM x
UNION ALL
SELECT p.*
FROM parents JOIN
table p
ON parents.ID = p.childid
),
children as (
SELECT top 1 *
FROM x
UNION ALL
SELECT p.*
FROM children JOIN
table p
parents.id = p.parentid
)
SELECT distinct *
FROM parents
UNION
SELECT distinct *
FROM children;
这是我希望结果返回的方式,所以 return id: 01,02,03,04,06 因为它们是 parent 或 child ID 04等
基本上我希望得到的是什么是进行递归查询以获取给定记录的 parent 和 child 的最佳方法,在哪里可以找到 children 你必须使用 1 列并且要获得 parents 必须使用另一列等等
这是伪 SQL 条款,但您只需要 2 个 CTE,无需 DISTINCT
即可获得您想要的结果。遍历分层数据,不使用 hierachyid
数据类型永远不会像它可能的那样有效,因为您需要递归。
无论如何,你实际上只想要这个:
USE Sandbox;
GO
CREATE TABLE dbo.YourTable (ID int, ParentID int);
INSERT INTO dbo.YourTable (ID,
ParentID)
VALUES(1,NULL),
(2,NULL),
(3,1),
(4,1),
(5,2),
(6,3),
(7,4),
(8,4),
(9,7),
(10,8);
GO
DECLARE @ID int = 4;
WITH Parents AS(
SELECT YT.ID,
YT.ParentID
FROM dbo.YourTable YT
WHERE YT.ID = @ID
UNION ALL
SELECT YT.ID,
YT.ParentID
FROM Parents P
JOIN dbo.YourTable YT ON P.ParentID = YT.ID),
Children AS(
SELECT YT.ID,
YT.ParentID
FROM dbo.YourTable YT
WHERE YT.ID = @ID
UNION ALL
SELECT YT.ID,
YT.ParentID
FROM Children C
JOIN dbo.YourTable YT ON C.ID = YT.ParentID)
SELECT ID, ParentID
FROM Parents P
UNION ALL
SELECT ID, ParentID
FROM Children C
WHERE C.ID != @ID --Stops the initial row being displayed twice
ORDER BY ID ASC;
GO
DROP TABLE dbo.YourTable;