【发布时间】:2020-06-30 05:06:19
【问题描述】:
我有如下图所示的表格。类别具有按 parent_id 的层次结构树。 CategoryProducts 在 Category 和 Product 之间建立了多对多的关系。一种产品可以属于不同的类别。例如“红球”可以放在“运动”和“运动”-s 子类别“足球”中。
如何使用子类别的产品数量计算每个类别中的产品数量?重复无关紧要,例如,类别“运动”可以包含两个“红球”(一个来自自己的类别,一个来自子类别“足球”)。
表关系:
结果表:
这是无法正常工作的 sql 脚本:
with recursive category_tree as (
select c.id , c.name , c.parent_id , count(cp.id) as amo
from temp_category_2 c
join temp_category_products cp on cp.category_id = c.id
where c.parent_id = null
group by c.id
union
select c2.id , c2.name , c2.parent_id , (select count(cp.id) from temp_category_products cp where cp.category_id = c2.id) as amo
from temp_category_2 c2
join category_tree ct on ct.id = c2.parent_id
)
select cat.id , cat.parent_id,
count(cp.id) + coalesce((
select sum(ct.amo)
from category_tree ct
where ct.parent_id = cat.id
group by ct.parent_id),0)as amount
from temp_category_2 cat
join temp_category_products cp on cp.category_id = cat.id
group by cat.id , cat.parent_id
;
表格类别:
id | name | parent_id | product_quantity
----+----------+-----------+------------------
2 | a | 1 | 3
3 | s | 1 | 3
4 | d | 2 | 3
5 | f | 2 | 4
6 | g | 3 | 2
1 | main | | 0
(6 rows)
表产品:
id | name
----+---------
1 | example
2 | example
3 | example
...
(15 rows)
表 category_products:
id | category_id | product_id
----+-------------+------------
1 | 6 | 1
2 | 6 | 2
3 | 5 | 3
4 | 5 | 4
5 | 5 | 5
6 | 5 | 6
7 | 4 | 7
8 | 4 | 8
9 | 4 | 9
10 | 3 | 10
11 | 3 | 11
12 | 3 | 12
13 | 2 | 13
14 | 2 | 14
15 | 2 | 15
(15 rows)
我的查询结果(不正确的结果):
id | parent_id | amount
----+-----------+--------
3 | 1 | 3
5 | 2 | 4
4 | 2 | 3
6 | 3 | 2
2 | 1 | 3
(5 rows)
正确的结果应该是:
id | parent_id | amount
----+-----------+--------
1 | | 15
2 | 1 | 10
3 | 1 | 5
4 | 2 | 3
5 | 2 | 4
6 | 3 | 2
(6 rows)
【问题讨论】:
-
我觉得你的问题很清楚,但它包含图像,某些用户很难看到。您能否以文本形式提供一个小样本数据,并显示您的查询从样本数据中找到了什么,以及它假设要找到什么?
-
@Scratte 我已经编辑了我的帖子。你能再检查一遍吗?
-
SQL 非常有帮助,谢谢 :) 我认为您的表应该显示为 ascii 表。同样的问题是很多用户将无法看到图像。我认为,如果您要给出无法正常工作的查询结果,它也会变得更容易。请注意,所有重要信息都应以文本形式提供。图像应该只是一个额外的可视化,这对你的表关系的前两个图像很好。您可以使用 this tool 创建 ascii 表 :)
标签: sql postgresql recursion common-table-expression