如何基于产品类别聚合订单数据生成报表视图(无需存储函数)
解决方案:用条件聚合实现视图化分类统计
当然有完美适配你需求的方案!不用存储函数,纯SQL就能搞定,而且完全适合创建视图——**条件聚合(Conditional Aggregation)**就是你要找的方法,结合子查询关联产品分类关系,一步到位得到目标报表。
先回顾你的数据与需求
订单表示例:
+----------+---------+-----+ | order_id | prod_id | qty | +----------+---------+-----+ | 1 | 1 | 2 | | 1 | 1 | 4 | | 1 | 3 | 1 | | 2 | 1 | 1 | | 2 | 2 | 2 | | 3 | 4 | 1 | | 3 | 4 | 2 | | 3 | 2 | 3 | | 3 | 3 | 5 | | 4 | 1 | 2 | | 4 | 2 | 3 | | 4 | 3 | 3 | | 4 | 4 | 3 | | 4 | 6 | 2 | +----------+---------+-----+
产品分类规则(来自product_class表):
- 类别1:product 1
- 类别2:products 2、3
- 类别3:products 4、6
期望按订单输出各分类的数量总计:
+----------+--------+--------+--------+ | order_id | c1_tot | c2_tot | c3_tot | +----------+--------+--------+--------+ | 1 | 6 | 1 | 0 | | 2 | 1 | 2 | 0 | | 3 | 0 | 8 | 3 | | 4 | 2 | 6 | 5 | +----------+--------+--------+--------+
实现代码(可直接创建视图)
CREATE VIEW order_class_totals AS SELECT o.order_id, -- 统计类别1的总数量 SUM(CASE WHEN pc.class = 1 THEN o.qty ELSE 0 END) AS c1_tot, -- 统计类别2的总数量(包含prod2、3) SUM(CASE WHEN pc.class = 2 THEN o.qty ELSE 0 END) AS c2_tot, -- 统计类别3的总数量(包含prod4、6) SUM(CASE WHEN pc.class = 3 THEN o.qty ELSE 0 END) AS c3_tot FROM orders o -- 子查询获取每个产品对应的分类,关联订单表 LEFT JOIN ( SELECT id AS prod_id, class FROM product_class ) pc ON o.prod_id = pc.prod_id GROUP BY o.order_id ORDER BY o.order_id;
代码解释
- 子查询关联分类:通过子查询把
product_class的id转成prod_id,和订单表的prod_id关联,自动匹配每个产品所属的分类,不用硬编码产品ID。 - 条件聚合:每个
SUM(CASE...)语句会判断当前行的产品是否属于目标分类,是就累加qty,否则加0,最终得到每个订单在对应分类下的总数量。 - LEFT JOIN的作用:确保即使订单里有未在
product_class中定义的产品,订单依然会被保留,对应的分类总计会显示0,避免数据丢失。 - 视图友好:整个逻辑是纯SELECT语句(加上CREATE VIEW),没有依赖存储函数,创建视图后可以直接像表一样查询使用。
验证结果
执行这个视图查询后,得到的结果完全符合你的期望:
- 订单1:c1_tot是2+4=6,c2_tot是prod3的1,c3_tot无对应产品所以为0
- 订单3:c2_tot是prod2的3+prod3的5=8,c3_tot是prod4的1+2=3
- 所有订单的分类统计都精准匹配目标输出
这个方案不仅简洁,而且效率比多次调用存储函数高得多,只需要一次扫描订单表和分类关联,非常适合长期使用的报表视图。
内容的提问来源于stack exchange,提问作者mngeek206
相关产品推荐
相关产品推荐

