针对特定 child 获取 parent 记录或针对 parent 获取 child 记录的查询是什么?

What is the query to get parent records against specific child or get child records against parent?

场景:

我的 table 中有以下层次结构格式的数据:

PERSON_ID   Name    PARENT_ID
1           Azeem   1
2           Farooq  2
3           Ahsan   3
4           Waqas   1
5           Adnan   1
6           Talha   2
7           Sami    2
8           Arshad  2
9           Hassan  8

例如

哈桑是 parent_id 8 中的 child,即 (Arshad)

Arshad 是 parent_id 2 的 child,即 (Farooq)

我想要的:

首先,我想找到特定parent_id的parent的所有parent。

例如:如果我想找到 Hassan 的 parent,那么我也会得到 Hassan 的 Parent,并且还得到它的 parent(Hassan -> Arshad -> Farooq )

其次,我想找到 Farooq 的所有 child,例如 (Farooq -> Arshad -> Hassan)

第三,如果 Azeem 也有相同的 parent 喜欢 (Azeem -> Azeem) 然后给我看这条记录。

我已经尝试过:

DECLARE @id INT
SET @id = 9

;WITH T AS (
    SELECT p.PERSON_ID,p.Name, p.PARENT_ID
        FROM hierarchy p
        WHERE p.PERSON_ID = @id AND p.PERSON_ID != p.PARENT_ID
    UNION ALL
    SELECT c.PERSON_ID,c.Name, c.PARENT_ID
        FROM hierarchy c
        JOIN T h ON h.PARENT_ID = c.PERSON_ID)
 SELECT h.PERSON_ID,h.Name FROM T h

它向我显示以下错误:

The statement terminated. The maximum recursion 100 has been exhausted before statement completion.

你的数据中有一个无限循环:Azeem 是他自己的 parent。您需要将他的值设置为 NULL 或将您的条件更改为 WHERE p.parent_id = @id AND p.parent_id != p.child_id.

另外,我觉得你的列命名方式不对 - primary-key 应该命名为 person_id 而不是 parent_id 而你的列实际上命名为 child_id指向那个人的parent,所以它应该被命名为parent_id

好吧,我为我的上述案例找到了一种方法:

如果我有以下 table 结构:

PERSON_ID   Name    PARENT_ID
1           Azeem   NULL
2           Farooq  NULL
3           Ahsan   NULL
4           Waqas   1
5           Adnan   1
6           Talha   2
7           Sami    2
8           Arshad  2
9           Hassan  8

然后我尝试了下面的查询,如果 Parent_ID 有 NULL 值意味着该记录不再有父项,它工作正常。

DECLARE @id INT
SET @id = 2

Declare @Table table(
    PERSON_ID bigint,
    Name varchar(50),
    PARENT_ID bigint
    );

;WITH T AS (
SELECT p.PERSON_ID,p.Name, p.PARENT_ID
    FROM hierarchy p
    WHERE p.PERSON_ID = @id AND p.PERSON_ID != p.PARENT_ID
UNION ALL
SELECT c.PERSON_ID,c.Name, c.PARENT_ID
    FROM hierarchy c
    JOIN T h ON h.PARENT_ID = c.PERSON_ID)
insert into @table 
select * from T;

IF exists(select * from @table)
BEGIN
    select PERSON_ID,Name from @table
End
Else
Begin
    select PERSON_ID,Name from Hierarchy
    where PERSON_ID = @id
end

上面的查询显示了当我设置参数值 @id = 1 时的期望输出

上面的查询显示了我设置参数值@id = 9 时的期望输出

问题:

我不想在 Parent_ID 中插入空值,就像如果那个人不再有父项,那么我会在 Parent_ID 列中插入相同的 Person_ID。 如果我用 person_id 替换空值,那么我会遇到以下错误。

The statement terminated. The maximum recursion 100 has been exhausted before statement completion.

如果我正确理解您的问题,即您不想在 Parent_ID 列中插入空值,那么您应该将 NULL 替换为 0,您更新后的代码将类似于:

;WITH DATA AS (
                SELECT p.PERSON_ID,p.Name, p.PARENT_ID
                FROM hierarchy p
                WHERE p.PERSON_ID = 9
                UNION ALL
                SELECT c.PERSON_ID,c.Name, c.PARENT_ID
                FROM hierarchy c
                JOIN DATA h 
                ON c.PERSON_ID = h.PARENT_ID 
          )
select * from DATA;