【问题标题】:Get child hierarchy for a subset of users获取用户子集的子层次结构
【发布时间】:2020-12-24 23:03:37
【问题描述】:

我有一个客户表,其中可以有父子记录的层次结构。
客户表的结构类似于,

customer { 
    id integer,
    user_id integer,
    parent_id integer
}

给定一个 user_id,我知道如何获取层次结构中属于给定 user_id 的所有子用户。比如user_id值为100,

WITH RECURSIVE subordinates AS (
SELECT c1.* 
FROM customer c1 
WHERE c1.user_id = 100 
UNION 
SELECT c2.* 
FROM customer c2 
INNER JOIN subordinates s 
ON s.id = c2.parent_id)
 
SELECT * FROM subordinates;

但我想将上述查询的输出限制为用户子集。因此,上述查询的第一个参数将是一个父 user_id(我们称之为parent_user),第二个参数将是一个 user_id 列表(我们称之为child_users)。

我想做的是,

  1. 迭代child_users
  2. 检查child_users 中的child_user 是否是parent_user 的子级
  3. 如果是,获取child_user 的整个子层次结构

以上 3 个步骤能否在单个 sql 查询中实现。请建议。

编辑

样本表数据可以,

id user_id  parent_id
-----------------------
1   100      null
2   101      100
3   102      101
4   103      102
5   104      100
6   105      null

因此,在表格中给出上述数据,对于parent_user = 100child_users = [101, 105] 的输入值,我希望检索以下输出,

id user_id  parent_id
-----------------------
2   101      100
3   102      101
4   103      102

带有id = 5 的记录不应成为输出的一部分,即使它有parent_id = 100,因为user_id 104 不在child_users 列表中。

【问题讨论】:

  • 请提供样本数据和所需的输出
  • @eshirvana FYI 添加了示例数据和所需的输出。

标签: sql postgresql hierarchical-data recursive-query


【解决方案1】:

请查看下面的答案,如果可行,请告诉我

declare @Customer  table ( Id int,userID int,parentID int)

insert @Customer (Id, userID, parentID)

select 1,100,null union all <br/>
select 1,101,100 union all <br/>
select 1,102,101 union all <br/>
select 1,103,102 union all <br/>
select 1,104,100 union all <br/>
select 1,105,null  <br/>

;with cte_emp as  <br/>
(  <br/>
select ID,userID,parentID 
from @Customer 
where  parentID=100 and userID in (101,105) <br/>
union all <br/>
select e.ID,e.userID,e.parentID
from @Customer e join cte_emp cte
on cte.userid=e.parentID <br/>
) <br/>

select * from cte_emp <br/>

【讨论】:

    【解决方案2】:

    如果我正确地跟随你,你想过滤起始节点的直接父节点。您可以将该条件放在 CTE 的锚点中:

    with recursive subordinates as (
        select c.* 
        from customer
        where user_id = any($1) and parent_id = $2
        union all
        select c.* 
        from customer c
        inner join subordinates s on s.id = c.parent_id
    )
    select * from subordinates;
    

    请注意,我将查询更改为接受输入参数:

    • $1 是一个子 ID 数组

    • $2是用于过滤的父级的id

    【讨论】:

    • 感谢@GMB 的回复。如果条目/user_id 是 parent_user 的子项,我想为 child_users 列表中的每个条目检索整个子项层次结构。我在问题中添加了一些示例数据和所需的输出。我尝试针对示例数据运行您的查询,但没有产生任何输出。
    猜你喜欢
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多