如何用单条SQL查询合并两个近似相同的MySQL表并补0?
问题描述
我有两个除金额列(分别为aug_amount、sep_amount)外几乎相同的MySQL表,希望通过SELECT查询将它们合并为一张展示两月金额的最终表。若某acc_id仅存在于其中一张表中,另一表对应的金额需默认设为0。
示例表
Table1
| id | acc_id | name | aug_amount |
|---|---|---|---|
| 1 | 123 | name1 | 100 |
| 2 | 456 | name2 | 200 |
| 3 | 333 | name3 | 300 |
Table2
| id | acc_id | name | sep_amount |
|---|---|---|---|
| 1 | 123 | name1 | 200 |
| 2 | 456 | name2 | 300 |
| 3 | 444 | name4 | 400 |
期望合并结果
| acc_id | name | aug_amount | sep_amount |
|---|---|---|---|
| 123 | name1 | 100 | 200 |
| 456 | name2 | 200 | 300 |
| 333 | name3 | 300 | 0 |
| 444 | name4 | 0 | 400 |
请问能否用单条SQL实现该需求?
解决方案
当然可以用单条SQL实现,以下是两种常用方案:
方案一:UNION ALL + 聚合函数(兼容性最优)
这种方法适用于所有MySQL版本,逻辑简单易懂:
SELECT acc_id, name, IFNULL(SUM(aug_amount), 0) AS aug_amount, IFNULL(SUM(sep_amount), 0) AS sep_amount FROM ( -- 提取Table1的八月数据,九月金额设为0 SELECT acc_id, name, aug_amount, 0 AS sep_amount FROM Table1 UNION ALL -- 提取Table2的九月数据,八月金额设为0 SELECT acc_id, name, 0 AS aug_amount, sep_amount FROM Table2 ) AS combined_data GROUP BY acc_id, name ORDER BY acc_id;
逻辑说明:
- 先通过
UNION ALL将两个表的结构统一,把缺失的月份金额设为0; - 按
acc_id和name分组,用SUM聚合对应月份的金额; - 用
IFNULL确保即使分组后无对应金额,也显示为0。
方案二:LEFT JOIN + RIGHT JOIN 模拟全外连接
MySQL本身不支持FULL OUTER JOIN,可以通过合并左连接和右连接的结果来实现:
SELECT COALESCE(t1.acc_id, t2.acc_id) AS acc_id, COALESCE(t1.name, t2.name) AS name, IFNULL(t1.aug_amount, 0) AS aug_amount, IFNULL(t2.sep_amount, 0) AS sep_amount FROM Table1 t1 LEFT JOIN Table2 t2 ON t1.acc_id = t2.acc_id UNION SELECT COALESCE(t1.acc_id, t2.acc_id) AS acc_id, COALESCE(t1.name, t2.name) AS name, IFNULL(t1.aug_amount, 0) AS aug_amount, IFNULL(t2.sep_amount, 0) AS sep_amount FROM Table1 t1 RIGHT JOIN Table2 t2 ON t1.acc_id = t2.acc_id;
逻辑说明:
- 第一个
LEFT JOIN保留Table1的所有记录,匹配Table2的对应记录; - 第二个
RIGHT JOIN保留Table2的所有记录,匹配Table1的对应记录; - 用
UNION去重交集部分的重复记录; - 用
COALESCE取非空的acc_id和name,IFNULL将空金额转为0。
两种方案都能得到你期望的合并结果。
内容的提问来源于stack exchange,提问作者henry434
相关产品推荐
相关产品推荐

