[英]MySQL - get children of a specific type from a hierarchical table
I have two tables, Groups and GroupHierarchy.我有两个表,Groups 和 GroupHierarchy。 They have the following data.
他们有以下数据。
GROUP:团体:
id | Name | type
8 | M.Sc | degree
4 | prog1 | programme
5 | prog2 | programme
1 | class1 | class
3 | class2 | class
GROUP HIERARCHY:组层次结构:
parentGroupId | childGroupId
8 | 4
8 | 5
4 | 1
5 | 3
prog1, prog2 of type programme are children of degree M.Sc.类型程序的 prog1、prog2 是硕士学位的孩子。
i want to perform the following query.我想执行以下查询。 Given the parent group id and required group type, the query should return all records of the required type that are children of the parent directly or indirectly.
给定父组 ID 和所需的组类型,查询应返回直接或间接属于父组的所需类型的所有记录。
Eg 1: Parent Group Id = 8, type = programme returns records 8 | eg 1: Parent Group Id = 8, type = program returns records 8 | 4 and 8 |
4 和 8 | 5. explanation: prog1(4) and prog2(5) are programmes under msc degree(8)
5.说明:prog1(4)和prog2(5)是msc degree(8)下的programs
Eg 2: Parent Group Id = 8, type = class returns records 4 |例2:Parent Group Id = 8, type = class 返回记录4 | 1 and 5 |
1 和 5 | 3. explanation: class1(1) and class2(3) are classes under msc degree(8)
3.说明:class1(1)和class2(3)是msc degree(8)下的classes
how to frame a query that returns the above results?如何构建返回上述结果的查询?
You can use a recursive CTE to retrieve the child arcs, then assemble a list of the child nodes, and finally filter by type.您可以使用递归 CTE 检索子弧,然后组装子节点列表,最后按类型过滤。
For example:例如:
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;
Result:结果:
id name type
--- ------ ---------
4 prog1 programme
5 prog2 programme
And by changing the parameter in the second line:并通过更改第二行中的参数:
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
Result:结果:
id name type
--- ------- -----
1 class1 class
3 class2 class
See running example at DB Fiddle .请参阅DB Fiddle中的运行示例。
EDIT - Explanation of the Query编辑 - 查询说明
The query includes three CTEs:该查询包括三个 CTE:
p
CTE defines the parameters. p
CTE 定义参数。r
CTE selects all the children of the starting node. r
CTE 选择起始节点的所有子节点。n
CTE walks the tree down and selects all children of the children, and so on. n
CTE 向下遍历树并选择子项的所有子项,依此类推。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.