如何用SQL按product subcategory计算销售额与退货额占比
按Product Subcategory计算销售额与退货额占比的SQL方案
刚好做过类似的零售数据分析需求,我来给你一套清晰可落地的SQL方案,顺便拆解每个部分的逻辑:
首先咱们先对齐核心规则:你的表里退货记录的quantity、total amount等字段是负数,正常销售是正数——那我们就基于total amount来区分销售和退货,因为它是最终的交易金额,比单独用数量更准确。
完整SQL查询
假设你的表名为transactions,执行下面的查询就能得到目标结果:
SELECT product_subcategory, -- 计算该子品类的总销售额:仅累加正的交易金额 SUM(CASE WHEN total_amount > 0 THEN total_amount ELSE 0 END) AS total_sales, -- 计算总退货额:累加负的交易金额后取绝对值(转成正数更符合日常表述) ABS(SUM(CASE WHEN total_amount < 0 THEN total_amount ELSE 0 END)) AS total_returns, -- 退货额占销售额的百分比(保留两位小数) ROUND( ABS(SUM(CASE WHEN total_amount < 0 THEN total_amount ELSE 0 END)) / NULLIF(SUM(CASE WHEN total_amount > 0 THEN total_amount ELSE 0 END), 0) * 100, 2 ) AS return_pct_of_sales, -- 可选:销售额占该子品类交易净额的百分比 ROUND( SUM(CASE WHEN total_amount > 0 THEN total_amount ELSE 0 END) / NULLIF(SUM(total_amount), 0) * 100, 2 ) AS sales_pct_of_net, -- 可选:退货额占该子品类交易净额的百分比 ROUND( ABS(SUM(CASE WHEN total_amount < 0 THEN total_amount ELSE 0 END)) / NULLIF(SUM(total_amount), 0) * 100, 2 ) AS return_pct_of_net FROM transactions -- 可选:排除金额为0的无效记录 WHERE total_amount != 0 GROUP BY product_subcategory ORDER BY product_subcategory;
关键细节说明
CASE WHEN筛选逻辑:精准区分销售和退货记录,只对符合条件的金额进行累加,避免相互干扰ABS()函数:把退货的负金额转换成正数,让“退货额”的结果更符合我们日常的认知习惯NULLIF()函数:专门用来避免除以0的报错——比如某个子品类只有退货没有销售时,分母会被设为NULL,结果返回NULL而非抛出错误ROUND()函数:把百分比保留两位小数,让最终结果更整洁直观,方便后续分析
灵活调整选项
- 如果你更习惯用
quantity字段判断销售/退货(比如正数量是销售,负数量是退货),可以把CASE WHEN的条件换成quantity > 0和quantity < 0,逻辑完全通用 - 如果不需要可选的净额占比字段,直接删掉对应的列即可
内容的提问来源于stack exchange,提问作者Zak
相关产品推荐
相关产品推荐

