mysql递归分组查询统计产品使用总次数

需要实现统计所有的父节点下面所有子节点产品之和
想实现比如效果

img


A应用 下所有子节点调用总次数
B应用 下所有子节点调用总次数


涉及3张表
一个平台应用表,一个平台下产品表,一个应用明细表
表明分别为:basic_platform,basic_introduce,logs_storage

img

img

img

麻烦问下,这种需要怎么实现,希望知道的各位告知呢。万分感激,请不要复制粘贴其他答案来凑数,需要正确的

首先先上结果:
其中平台应用表为 t1,平台下产品表为 t2, 应用明细表为 t3

select temp2.platform_id AS '平台应用id',t1.platform_name AS '平台应用名称',SUM(temp2.total_piece) AS '该平台下所有产品的扣除总次数之和'
from t1 
inner join (
        select t2.platform_id AS platform_id,t3.app_key AS app_key,SUM(t3.piece) AS total_piece
        from t2
        inner join t3 on t2.app_key = t3.app_key 
        group by t3.app_key,t2.platform_id
) temp2 on t1.platform_id = temp2.platform_id
group by temp2.platform_id,t1.platform_name

解题思路:


-- 1、表名明确  
-- 首先确定 平台应用表为 t1,平台下产品表为 t2, 应用明细表为 t3

-- 2、表关系明确
-- 其中 t2 平台下产品表中的 platform_id 与 t1 平台应用表中的平台id 为关联关系
-- t3 与 t2 中的 app_key 为关联字段

-- 3、t1 与 t2 为一对多,t2 与 t3 是一对多

-- 开始解题
-- 首先计算出单个产品的 扣除总次数
select app_key,SUM(piece) AS total_piece FROM t3 group by app_key;

-- 将上方的单个产品的 扣除总计数关联到 t2 表中
select t2.id,t2.platform_id,t2.app_key,temp1.total_piece
from t2
inner join (select app_key,SUM(piece) AS total_piece FROM t3 group by app_key) temp1 on t2.app_key = temp1.app_key

-- 上方为拆分想法思路方便理解所写,其实我们可以将上面两步操作合起来,采用下面这种方式一样能够达到同样效果

select t2.platform_id,t3.app_key,SUM(t3.piece) AS total_piece
from t2
inner join t3 on t2.app_key = t3.app_key 
group by t3.app_key,t2.platform_id

-- 如上我们就得到了一张具有 t2.platform_id 与 根据 t3 计算出来的单个产品的扣除总次数数据表
-- 下面我们将此数据表做为 临时数据表temp2 与 t1 关联得到最终的结果,具体操作如下

select temp2.platform_id AS '平台应用id',t1.platform_name AS '平台应用名称',SUM(temp2.total_piece) AS '该平台下所有产品的扣除总次数之和'
from t1 
inner join (
        select t2.platform_id AS platform_id,t3.app_key AS app_key,SUM(t3.piece) AS total_piece
        from t2
        inner join t3 on t2.app_key = t3.app_key 
        group by t3.app_key,t2.platform_id
) temp2 on t1.platform_id = temp2.platform_id
group by temp2.platform_id,t1.platform_name

如果需要实现统计所有的父节点下面所有子节点产品之和,可以使用MySQL中的递归查询语句,以下是一种可能的实现方法:

首先,假设我们有一个表product,其中包含以下字段:

id: 产品ID
name: 产品名称
parent_id: 父产品ID
count: 出库数量
接着,我们可以使用递归查询语句来统计每个父节点下所有子节点产品的使用总次数,方法如下:
WITH RECURSIVE cte AS ( SELECT id, name, parent_id, count FROM product WHERE parent_id IS NULL -- 找到顶级节点 UNION ALL SELECT p.id, p.name, p.parent_id, p.count FROM product p INNER JOIN cte c ON c.id = p.parent_id ) SELECT IFNULL(pt.name, '总计') AS '项目本期', IFNULL(p.name, '总计') AS '产品名称', SUM(cte.count) AS '出库数量' FROM cte LEFT JOIN product p ON cte.id = p.id LEFT JOIN product pt ON p.parent_id = pt.id GROUP BY pt.id, p.id WITH ROLLUP; -- 使用 ROLLUP 进行分组小计和总计
上述查询语句使用了 MySQL 的递归查询语句 WITH RECURSIVE,并使用了左连接和 GROUP BY ROLLUP 进行分组小计和总计。运行后,可以得到类似下面的结果:
项目本期 | 产品名称 | 出库数量 -------- | -------- | -------- A项目 | 产品A1 | 20 A项目 | 产品A2 | 30 A项目 | 小计 | 50 B项目 | 产品B1 | 10 B项目 | 产品B2 | 20 B项目 | 小计 | 30 总计 | 总计 | 80
其中,“小计”是每个父节点下所有子节点产品的出库数量之和,“总计”是所有产品的出库数量之和。

需要注意的是,这种递归查询语句在数据量较大时可能会比较慢,因此需要考虑性能问题。

或者这样

WITH RECURSIVE cte AS (
  SELECT id, project, quantity, parent_id, id AS root_id
  FROM products
  WHERE parent_id IS NULL -- 获取所有根节点
  UNION ALL
  SELECT p.id, p.project, p.quantity, p.parent_id, c.root_id
  FROM products p
  JOIN cte c ON p.parent_id = c.id
)
SELECT 
  CASE 
    WHEN parent_id IS NULL THEN project -- 如果是根节点,则直接输出项目名称
    ELSE CONCAT((SELECT project FROM products WHERE id = root_id), ' - ', project) -- 否则,输出根节点项目名称与子节点名称的组合
  END AS project,
  SUM(quantity) AS quantity,
  IF(parent_id IS NULL, 
     (SELECT SUM(quantity) FROM cte WHERE root_id = id), -- 如果是根节点,则统计其所有子节点的出库数量之和
     NULL) AS child_quantity
FROM cte
GROUP BY root_id, project;

这里使用了MySQL的CTE(Common Table Expression)以及递归查询功能。首先,使用CTE获取所有根节点,然后递归查询其所有子节点,并标记它们的根节点ID,最后按照根节点ID和项目名称分组统计出库数量和子节点出库数量之和。