繁体   English   中英

MySQL - 从分层表中获取特定类型的孩子

[英]MySQL - get children of a specific type from a hierarchical table

我有两个表,Groups 和 GroupHierarchy。 他们有以下数据。

团体:

id   |  Name      | type

8    |  M.Sc      | degree  
4    |  prog1     | programme   
5    |  prog2     | programme   
1    |  class1    | class   
3    |  class2    | class

组层次结构:

parentGroupId | childGroupId

8             | 4

8             | 5

4             | 1

5             | 3

类型程序的 prog1、prog2 是硕士学位的孩子。

我想执行以下查询。 给定父组 ID 和所需的组类型,查询应返回直接或间接属于父组的所需类型的所有记录。

eg 1: Parent Group Id = 8, type = program returns records 8 | 4 和 8 | 5.说明:prog1(4)和prog2(5)是msc degree(8)下的programs

例2:Parent Group Id = 8, type = class 返回记录4 | 1 和 5 | 3.说明:class1(1)和class2(3)是msc degree(8)下的classes

如何构建返回上述结果的查询?

您可以使用递归 CTE 检索子弧,然后组装子节点列表,最后按类型过滤。

例如:

with recursive
p as (select 8 as id, 'programme' as type),
r as (select h.* from h cross join p where h.parentGroupId = p.id),
n as (
  select * from r
 union all
  select h.*
  from n
  join h on h.parentGroupId = n.childGroupId
)
select g.*
from (
  select childGroupId as id from n
  union all select distinct parentGroupId from r
) a
join g on g.id = a.id
join p on p.type = g.type;

结果:

 id  name   type      
 --- ------ --------- 
 4   prog1  programme 
 5   prog2  programme 

并通过更改第二行中的参数:

with recursive
p as (select 8 as id, 'class' as type),
r as (select h.* from h cross join p where h.parentGroupId = p.id),
n as (
  select * from r
 union all
  select h.*
  from n
  join h on h.parentGroupId = n.childGroupId
)
select g.*
from (
  select childGroupId as id from n
  union all select distinct parentGroupId from r
) a
join g on g.id = a.id
join p on p.type = g.type

结果:

 id  name    type  
 --- ------- ----- 
 1   class1  class 
 3   class2  class 

请参阅DB Fiddle中的运行示例。

编辑 - 查询说明

该查询包括三个 CTE:

  • p CTE 定义参数。
  • r CTE 选择起始节点的所有子节点。
  • n CTE 向下遍历树并选择子项的所有子项,依此类推。
  • 最后,主查询检索每个节点的类型,并根据它进行过滤。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM