如何在SQL中基于多列匹配条件计算分组内列值占比百分比
按多列分组计算占比的SQL实现方法
你需要的是将每行的Total值,除以Date、Cust、Sector、Type四列完全匹配的分组内所有Total的总和,以此得到占比。以下是两种可行的实现方式:
方法一:使用窗口函数(推荐,适用于MySQL 8.0+、PostgreSQL、SQL Server等现代SQL数据库)
窗口函数可以直接在查询中按指定分组计算总和,无需额外关联子查询:
SELECT COUNTRY, DATE, CUST, SECTOR, TYPE, SUM(TOTAL) AS total, -- 按Date、Cust、Sector、Type分组计算总和,再求占比 ROUND(SUM(TOTAL) / SUM(SUM(TOTAL)) OVER (PARTITION BY DATE, CUST, SECTOR, TYPE), 4) AS percent FROM Data GROUP BY COUNTRY, DATE, CUST, SECTOR, TYPE;
代码说明:
SUM(SUM(TOTAL)) OVER (PARTITION BY DATE, CUST, SECTOR, TYPE):外层SUM(TOTAL)是当前COUNTRY+DATE+CUST+SECTOR+TYPE分组的总计,内层SUM(...) OVER (...)则是按Date、Cust、Sector、Type这四列分组的全局总计ROUND(...,4):将结果保留4位小数,可根据需求调整位数
运行后你的测试数据会得到如下结果:
| 国家 | 日期 | 客户 | 行业领域 | 类型 | total | percent |
|---|---|---|---|---|---|---|
| US | 201902 | ABCD | ABC-DEF | OTHER | 312 | 0.0725 |
| DE | 201902 | ABCD | ABC-DEF | OTHER | 3987 | 0.9275 |
| US | 201902 | ABCD | DEF-GHI | MAIN | 122 | 1.0000 |
方法二:子查询关联(兼容旧版本MySQL等不支持窗口函数的数据库)
如果你的数据库不支持窗口函数,可以先计算每个目标分组的总和,再通过关联查询计算占比:
SELECT d.COUNTRY, d.DATE, d.CUST, d.SECTOR, d.TYPE, SUM(d.TOTAL) AS total, ROUND(SUM(d.TOTAL)/g.group_total, 4) AS percent FROM Data d JOIN ( -- 先计算Date、Cust、Sector、Type分组的总计 SELECT DATE, CUST, SECTOR, TYPE, SUM(TOTAL) AS group_total FROM Data GROUP BY DATE, CUST, SECTOR, TYPE ) g ON d.DATE = g.DATE AND d.CUST = g.CUST AND d.SECTOR = g.SECTOR AND d.TYPE = g.TYPE GROUP BY d.COUNTRY, d.DATE, d.CUST, d.SECTOR, d.TYPE;
代码说明:
- 子查询
g先算出每个Date、Cust、Sector、Type组合的总Total - 主查询将原表数据与子查询结果关联,用当前行的
Total总和除以对应分组的总Total得到占比
内容的提问来源于stack exchange,提问作者Alex S
相关产品推荐
相关产品推荐

