获取针对特定子项的父记录或针对父项获取子记录的查询是什么?

时间:2017-09-06 22:35:56

标签: sql sql-server hierarchical-data

情境:

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

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

E.g

Hassan是parent_id 8的孩子,是(Arshad)

和Arshad是parent_id 2的孩子,是(Farooq)

我想要的是什么:

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

例如:如果我想找到Hassan的父母,那么我也会得到Hassan的父母,也可以得到它的父母(Hassan - > Arshad - > Farooq)

其次,我想找到Farooq的所有孩子(Farooq - > Arshad - > Hassan)

第三,如果Azeem也有同样的父母(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

它显示我的错误:

  

声明终止。在语句完成之前,最大递归100已经用尽。

3 个答案:

答案 0 :(得分:1)

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

另外,我觉得你的列被命名为错误的方式 - 主键应该命名为person_id而不是parent_id,而名为child_id的列实际上指向那个人& #39; s ,因此应将其命名为parent_id

答案 1 :(得分:1)

如果我正确理解您的问题,您不想在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;

答案 2 :(得分:0)

我找到了一个方法,我的上述情况是:

如果我有以下表结构:

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

时,上面的查询显示了我想要的输出

enter image description here

当我设置参数值@id = 9

时,上面的查询显示了我想要的输出

enter image description here

<强>问题:

我不想在Parent_ID中插入空值,就好像没有该Person的Parent,然后我在Parent_ID列中插入相同的Person_ID。 如果我用person_id替换空值,那么我得到以下错误。

  

声明终止。在语句完成之前,最大递归100已经用尽。