使用MySQL 8.0递归CTE查找层次结构表中的直接后代并传播给父级

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用MySQL 8.0递归CTE查找层次结构表中的直接后代并传播给父级相关的知识,希望对你有一定的参考价值。

我正在尝试在层次结构的每个节点上积累直接后代的数量。对于没有后代的节点,计数应为0。

通常,我想在未完全定义层次结构的多个上下文中应用不同类型的计数/汇总。因此,我对递归解决方案感兴趣。

请考虑以下代码。如何“反转”此查询,以使我无需计算深度,而是计算后代并向上传播数字?

create table hierarchy (
    name     varchar(100),
    location varchar(100),
    parent_name varchar(100),
    parent_location varchar(100)
) engine=InnoDB default charset=UTF8MB4;

truncate hierarchy;
insert into hierarchy values
    ('music', '/', NULL, NULL),
    ('classical', '/music', 'music', '/'),
    ('pop', '/music', 'music', '/'),
    ('rock', '/music', 'music', '/'),
    ('bach', '/music/classical', 'classical', '/music');
select * from hierarchy;

with recursive cte as
(
    select name, location, parent_name, parent_location, 1 as depth
    from hierarchy where parent_name is NULL and parent_location is NULL
    union all
    select a.name, a.location, a.parent_name, a.parent_location, depth + 1
    from hierarchy as a inner join cte on a.parent_name = cte.name and a.parent_location = cte.location
)
select *
from cte;

输出是

name         location           parent_name   parent_location   depth
'music'      '/'                NULL          NULL              1
'classical'  '/music'           'music'       '/'               2
'pop'        '/music'           'music'       '/'               2
'rock'       '/music'           'music'       '/'               2
'bach'       '/music/classical' 'classical'   '/music'          3

我最终感兴趣的是此输出:

name         location           parent_name   parent_location   descendents
'music'      '/'                NULL          NULL              3
'classical'  '/music'           'music'       '/'               1
'pop'        '/music'           'music'       '/'               0
'rock'       '/music'           'music'       '/'               0
'bach'       '/music/classical' 'classical'   '/music'          0
    

我正在尝试在层次结构的每个节点上积累直接后代的数量。对于没有后代的节点,计数应为0。通常,我想应用不同的...

答案

您似乎正在计算每个节点的直接后代数量。如果是这样,我认为您不需要递归查询:应该使用一个简单的子查询:

以上是关于使用MySQL 8.0递归CTE查找层次结构表中的直接后代并传播给父级的主要内容,如果未能解决你的问题,请参考以下文章

如何获得递归 CTE 中生成的最后一条记录?

CTE递归获取树层次结构

优化 CTE 以在父子层次结构的某个级别返回后代

如何在T-SQL中使用递归CTE获得完整的层次结构?

MYSQL 8.019 CTE 递归查询怎么解决死循环三种方法

SQL Server CTE 递归查询全解