MySQL 5.7按Name、EID分组求和并保留所有原始行的实现方法
问题描述
现有数据表如下:
| NAME | AMT | EID | Tran |
|---|---|---|---|
| John | 4000 | 1 | T1 |
| Mary | 5000 | 2 | T2 |
| John | 8000 | 1 | T3 |
| Willi | 5000 | 3 | T4 |
| Mary | 1000 | 2 | T5 |
需求:按NAME、EID分组对AMT列求和,同时保留所有原始行数据,输出格式如下:
| NAME | AMT | EID | Tran | Total Amt |
|---|---|---|---|---|
| John | 4000 | 1 | T1 | 12000 |
| Mary | 5000 | 2 | T2 | 6000 |
| John | 8000 | 1 | T3 | 12000 |
| Willi | 5000 | 3 | T4 | 5000 |
| Mary | 1000 | 2 | T5 | 6000 |
尝试了以下SQL语句但未生效,且当前使用的MySQL 5.7不支持LEAD和LAG函数,请问如何实现目标输出?
select SUM(AMT) as TotalAmt, * from mytable group by NAME,EID
解决方案
你之前的SQL语句问题在于GROUP BY NAME,EID后只能返回每组的聚合结果,无法保留所有原始行。在MySQL 5.7中可以用以下两种方法实现需求:
方法一:子查询关联
先通过子查询计算每个NAME+EID分组的总金额,再将原表与这个子查询结果关联:
SELECT t.NAME, t.AMT, t.EID, t.Tran, g.Total_Amt FROM mytable t JOIN ( SELECT NAME, EID, SUM(AMT) AS Total_Amt FROM mytable GROUP BY NAME, EID ) g ON t.NAME = g.NAME AND t.EID = g.EID;
方法二:使用窗口函数(MySQL 5.7支持)
MySQL 5.7虽然不支持LEAD/LAG,但支持SUM() OVER()窗口函数,直接在原表上计算分组总金额:
SELECT NAME, AMT, EID, Tran, SUM(AMT) OVER(PARTITION BY NAME, EID) AS `Total Amt` FROM mytable;
这两种方法都能满足需求,窗口函数写法更简洁,子查询关联则兼容性更广(如果遇到不支持窗口函数的场景)。
内容的提问来源于stack exchange,提问作者user24945713
相关产品推荐
相关产品推荐

