group by 必须配合聚合函数或出现在group by子句中,否则报错;财务对账需区分收支方向、明确汇总目标,并确保原始数据干净。

GROUP BY 必须配合聚合函数,否则报错 ERROR 1140: Mixing of GROUP columns
直接写 SELECT account_id, amount FROM transactions GROUP BY account_id 会触发 MySQL 严格模式报错。SQL 标准要求:所有非聚合字段必须出现在 GROUP BY 子句中,或被包裹在 SUM()、COUNT()、MAX() 等聚合函数里。
财务对账场景下,常见错误是试图“保留某笔明细的同时按账户分组”,这违背了分组语义。正确做法是明确汇总目标:
- 余额 =
SUM(amount)(注意:收入为正、支出为负,或统一用direction字段区分) - 交易笔数 =
COUNT(*) - 最早/最晚交易时间 =
MIN(created_at)/MAX(created_at) - 是否含异常单 =
COUNT(CASE WHEN status != 'success' THEN 1 END)
对账需区分「发生额」和「余额」,别直接 SUM(amount) 就完事
很多初学者把所有 amount 直接加总,结果发现和银行流水对不上——因为没处理方向性。真实业务中,同一张表常存入、支出混记,必须靠字段标识流向。
假设表结构含 amount DECIMAL(12,2) 和 type VARCHAR(10)(值为 'income' 或 'expense'),则正确汇总逻辑是:
SELECT account_id, SUM(CASE WHEN type = 'income' THEN amount ELSE 0 END) AS total_income, SUM(CASE WHEN type = 'expense' THEN amount ELSE 0 END) AS total_expense, SUM(CASE WHEN type = 'income' THEN amount ELSE -amount END) AS net_balance FROM transactions WHERE date BETWEEN '2024-01-01' AND '2024-01-31' GROUP BY account_id;
漏掉 CASE 转向或误用绝对值,会导致净额符号全反,对账差额永远是两倍。
多维度对账时,GROUP BY 字段顺序影响结果可读性,但不影响计算逻辑
比如要按「账户+币种+月份」三级汇总,写成 GROUP BY account_id, currency, YEAR(date), MONTH(date) 没问题,但导出 Excel 后,若想看某账户下各币种分布,字段顺序不合理会让数据分散。
建议按高频筛选维度前置:
- 主对账单位(如
account_id)放最前 - 时间粒度(如
DATE_FORMAT(date, '%Y-%m'))次之,便于后续加HAVING过滤 - 辅助维度(如
currency、channel)放最后
注意:DATE_FORMAT(date, '%Y-%m') 比 YEAR(date), MONTH(date) 更安全——避免跨年时 2023-12 和 2024-01 被当成同月分组。
对账差异定位:用 LEFT JOIN 对比两个汇总结果集
自动汇总后发现某账户差 0.01 元?别手动翻表。用 SQL 直接比对「我方汇总」和「银行文件导入表」:
SELECT a.account_id, a.net_balance AS our_balance, b.balance AS bank_balance, a.net_balance - b.balance AS diff FROM ( SELECT account_id, SUM(CASE WHEN type='income' THEN amount ELSE -amount END) AS net_balance FROM transactions GROUP BY account_id ) a LEFT JOIN bank_statement b ON a.account_id = b.account_id WHERE ABS(a.net_balance - b.balance) > 0.005;
关键点:
- 用
ABS(...)>0.005容忍浮点精度误差,别写!= 0 - 银行表若含重复行或未去重,先
GROUP BY再 JOIN,否则产生笛卡尔积 - 时间范围必须严格一致,两个子查询都要加
WHERE date条件,不能只在外部加
真正难的不是写出 GROUP BY,而是确认每笔原始记录的方向、状态、时间归属是否干净——脏数据进,再漂亮的分组也出不来可信对账结果。











