MySQL-父项的总和+;子类别
我有两张桌子: 父子“类别”:MySQL-父项的总和+;子类别,mysql,parent-child,Mysql,Parent Child,我有两张桌子: 父子“类别”: id name parent_id 1 Food NULL 2 Pizza 1 3 Pasta 2 ‘交易’: id amount category_id 1 100 1 2 50 2 3 25 2 我想返回所有类别以及两个总列: 总计=具有此类别id的所有交易的金额之和
id name parent_id
1 Food NULL
2 Pizza 1
3 Pasta 2
‘交易’:
id amount category_id
1 100 1
2 50 2
3 25 2
我想返回所有类别以及两个总列:
总计=具有此类别id的所有交易的金额之和
parentTotal=总计+其所有子类别的总计
示例(使用上表):
编辑:
代码已更新(基于下面Nedret Recep的代码),运行良好
SELECT
tmp1.id, tmp1.name, tmp1.parent_id, tmp1.total, IFNULL(tmp1.total, 0) + IFNULL(tmp2.s, 0) AS parenttotal
FROM
(SELECT
ca.id, ca.name, ca.parent_id, SUM(tr.amount) as total
FROM
categories ca
LEFT JOIN
transactions tr
ON
tr.category_id = ca.id
GROUP BY
ca.id)
AS tmp1
LEFT JOIN
(SELECT
c.id, c.parent_id as categoryid, SUM(t.amount) AS s
FROM
transactions t
RIGHT JOIN
categories c
ON
t.category_id = c.id
GROUP BY
c.parent_id)
AS tmp2
ON tmp2.categoryid = tmp1.id
order by coalesce(tmp1.parent_id, tmp1.id), tmp1.parent_id
我真的很感谢你的帮助-谢谢 通过一个内部联接,我们计算标准类别中的总数。然后,通过另一个内部联接,我们计算总和,但这次是按父对象id分组。然后,我们联接两个结果表,使两个总和在一行中。对于大型表,此查询速度较慢,因此应用程序级别的替代方法会更好
SELECT
tmp1.id, tmp1.name, tmp1.parent_id, tmp1.total, tmp1.total + tmp2.s AS parenttotal
FROM
(SELECT
ca.id, ca.name, ca.parent_id, SUM(tr.amount) as total
FROM
transactions tr
INNER JOIN
categories ca
ON
tr.categoru_id = ca.id
GROUP BY
ca.id)AS tmp1
LEFT OUTER JOIN
(
SELECT
c.parent_id as categoryid, SUM(t.amount) AS s
FROM
transactions t
INNER JOIN
categories c
ON
t.category_id = c.i
GROUP
BY c.id ) AS tmp2
ON
tmp2.categoryid = tmp.id
类别是仅在两个级别上,还是具有无限深度的树状结构?也就是说,类别比萨饼也可以有子类别。只有两级树和无限级树会有不同的方法。是的,类别只有两级深。谢谢你,我在你的基础上修改了我的答案,更新了我的代码。一切都很好。但是,如果父类别没有交易记录,则合计和父合计都返回零-即,它不会将子交易记录的合计相加。知道为什么吗?感谢您将
tmp1.total+tmp2.s
替换为IFNULL(tmp1.total,0)+tmp2.s
IFNULL有助于将NULL转换为0,并保留值。@ginsberg:实际上您可能还需要将IFNULL()
应用于tmp2.s
。谢谢大家。现在效果很好。以上代码已更新。
SELECT
tmp1.id, tmp1.name, tmp1.parent_id, tmp1.total, tmp1.total + tmp2.s AS parenttotal
FROM
(SELECT
ca.id, ca.name, ca.parent_id, SUM(tr.amount) as total
FROM
transactions tr
INNER JOIN
categories ca
ON
tr.categoru_id = ca.id
GROUP BY
ca.id)AS tmp1
LEFT OUTER JOIN
(
SELECT
c.parent_id as categoryid, SUM(t.amount) AS s
FROM
transactions t
INNER JOIN
categories c
ON
t.category_id = c.i
GROUP
BY c.id ) AS tmp2
ON
tmp2.categoryid = tmp.id