如何用SQL按月份分组两张表并计算金额差值?
解决方案
你可以通过先分别对两张表按月份聚合金额,再关联两个聚合结果的方式,得到包含金额差值的合并报表。
完整SQL实现(以MySQL为例)
SELECT -- 统一显示月份,处理单侧无数据的情况 CASE WHEN t1.月份_num IS NOT NULL THEN t1.月份_cn ELSE t2.月份_cn END AS 月份, IFNULL(t1.金额1, 0) AS 金额1, IFNULL(t2.金额2, 0) AS 金额2, IFNULL(t1.金额1, 0) - IFNULL(t2.金额2, 0) AS `金额1-金额2` FROM ( -- 表1按月份分组求和,同时生成数字月份用于排序 SELECT CASE MONTH(STR_TO_DATE(日期, '%d/%m/%Y')) WHEN 1 THEN '一月' WHEN 2 THEN '二月' WHEN 3 THEN '三月' WHEN 4 THEN '四月' WHEN 5 THEN '五月' WHEN 6 THEN '六月' WHEN 7 THEN '七月' WHEN 8 THEN '八月' WHEN 9 THEN '九月' WHEN 10 THEN '十月' WHEN 11 THEN '十一月' WHEN 12 THEN '十二月' END AS 月份_cn, MONTH(STR_TO_DATE(日期, '%d/%m/%Y')) AS 月份_num, SUM(金额1) AS 金额1 FROM 表1 GROUP BY 月份_cn, 月份_num ) t1 -- 用FULL JOIN确保所有月份都被保留,即使某张表无对应数据 FULL JOIN ( -- 表2按月份分组求和 SELECT CASE MONTH(STR_TO_DATE(日期, '%d/%m/%Y')) WHEN 1 THEN '一月' WHEN 2 THEN '二月' WHEN 3 THEN '三月' WHEN 4 THEN '四月' WHEN 5 THEN '五月' WHEN 6 THEN '六月' WHEN 7 THEN '七月' WHEN 8 THEN '八月' WHEN 9 THEN '九月' WHEN 10 THEN '十月' WHEN 11 THEN '十一月' WHEN 12 THEN '十二月' END AS 月份_cn, MONTH(STR_TO_DATE(日期, '%d/%m/%Y')) AS 月份_num, SUM(金额2) AS 金额2 FROM 表2 GROUP BY 月份_cn, 月份_num ) t2 ON t1.月份_num = t2.月份_num -- 按月份顺序排序 ORDER BY COALESCE(t1.月份_num, t2.月份_num)
关键说明
- 日期转换:用
STR_TO_DATE将字符串日期转为日期类型,再通过MONTH提取月份数字,用CASE转为中文月份名称。 - 分组聚合:子查询分别对两张表按月份计算总金额。
- 关联合并:使用
FULL JOIN确保两张表中的所有月份都能出现在结果中,用IFNULL将NULL值替换为0,避免差值计算出错。 - 排序:通过月份数字排序,保证结果按一月、二月的顺序展示。
不同数据库适配
如果使用其他数据库,只需调整日期处理函数:
- SQL Server:用
CONVERT(DATE, 日期, 103)转换日期,DATEPART(MONTH, ...)配合CASE转中文月份。 - Oracle:用
TO_DATE(日期, 'DD/MM/YYYY')转换日期,TO_CHAR(..., 'MM')提取月份数字后配合CASE转中文。
内容的提问来源于stack exchange,提问作者bloumk
相关产品推荐
相关产品推荐

