MySQL 8.0查询,根据下游内容递归计算层次结构中每个节点的大小

MySQL 8.0查询,根据下游内容递归计算层次结构中每个节点的大小,mysql,hierarchical-data,recursive-query,Mysql,Hierarchical Data,Recursive Query,这是在MySQL 8.0中实现的 如何使用递归查询自下而上计算每个类别节点(type=1)的大小 从层次结构中的一个给定节点开始,在本例中,我如何通过递归地将层次结构中(type=2)的文件大小相加来获得每个直系后代类别组(type=1)的大小 name location parent_name parent_location total size 'music' '/' NULL NULL

这是在MySQL 8.0中实现的

如何使用递归查询自下而上计算每个类别节点(type=1)的大小

从层次结构中的一个给定节点开始,在本例中,我如何通过递归地将层次结构中(type=2)的文件大小相加来获得每个直系后代类别组(type=1)的大小

name         location           parent_name   parent_location   total size
'music'      '/'                NULL          NULL              7164
'classical'  '/music'           'music'       '/'               3072
'pop'        '/music'           'music'       '/'               4092
'bonjovi'    '/music/pop'       'pop'         '/music'          4092
'bach'       '/music/classical' 'classical'   '/music'          3072
...
最初,类型为1的节点具有默认值。查询根据下游内容递归计算大小


为了方便起见,可以使用fiddle space:

您可以使用一对递归CTE解决此问题。第一个查找基于给定节点的所有类别(在本例中为
音乐
),第二个查找与每个类别关联的所有文件,并构建一个包含所有类别(直到根类别)的大小表。然后将此表连接到类别表,并在每个级别汇总文件大小:

WITH RECURSIVE categories AS (
  SELECT name, location, parent_name, parent_location, size
  FROM hierarchy
  WHERE name = 'music'
  UNION ALL
  SELECT h.name, h.location, h.parent_name, h.parent_location, h.size
  FROM hierarchy h
  JOIN categories c ON c.name = h.parent_name
  WHERE h.type = 1
),
filesizes AS (
  SELECT size, parent_name
  FROM hierarchy
  WHERE type = 2 AND parent_name IN (SELECT name FROM categories)
  UNION ALL
  SELECT f.size, h.parent_name
  FROM hierarchy h
  JOIN filesizes f ON f.parent_name = h.name
  WHERE h.parent_name IS NOT NULL
)
SELECT c.name, c.location, c.parent_name, c.parent_location,
       SUM(f.size) AS total_size
FROM categories c
JOIN filesizes f ON f.parent_name = c.name
GROUP BY c.name, c.location, c.parent_name, c.parent_location
输出:

name        location            parent_name     parent_location     total_size
music       /                   null            null                7164
classical   /music              music           /                   3072
pop         /music              music           /                   4092
bonjovi     /music/pop          pop             /music              4092
bach        /music/classical    classical       /music              3072

这真是太棒了,我尝试了各种聚合和CTE,但根本不知道如何进行自底向上的传播。我会仔细研究的,谢谢。@LucasTaddeus是的-一个棘手的问题。我建议单独查看每个CTE的输出,例如,并帮助了解其工作原理。我很感激,如果没有专家指导,这些方法很难及时理解。
name        location            parent_name     parent_location     total_size
music       /                   null            null                7164
classical   /music              music           /                   3072
pop         /music              music           /                   4092
bonjovi     /music/pop          pop             /music              4092
bach        /music/classical    classical       /music              3072