递归查询 - 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;