如何使用SQL连接两张全量表并按城市汇总总人数?
原查询写法的缺陷
你最初写的查询存在两个核心问题:
- 关联条件字段写错:两张表的城市字段名分别是
column_name1、column_name2,原语句中写的table1.column_name是不存在的无效字段 - 关联逻辑有漏洞:仅用
LEFT JOIN只能保留左表table1的所有城市,table2独有的城市会被直接丢弃;同时未匹配到的记录对应字段值为NULL,NULL和任何数值做加法运算结果都是NULL,会导致仅出现在单表的城市统计值出错。
通用SQL实现方案
方案1:全外连接写法(适配支持全外连接的引擎:PostgreSQL、Oracle、SQL Server等)
用FULL OUTER JOIN保留两张表的所有记录,配合COALESCE函数处理空值,直接计算总和:
SELECT COALESCE(t1.column_name1, t2.column_name2) AS column_name, COALESCE(t1.number_P1, 0) + COALESCE(t2.number_P2, 0) AS number_P FROM table1 t1 FULL OUTER JOIN table2 t2 ON t1.column_name1 = t2.column_name2;
逻辑说明:
FULL OUTER JOIN会返回两表所有记录,无论是否能匹配上关联条件,覆盖「仅在table1存在」「仅在table2存在」「两表都存在」三类城市场景COALESCE(值, 0)的作用是当对应表中没有该城市记录、数值为NULL时,按0参与计算,避免加法结果为NULL- 外层
COALESCE取城市名时,优先取table1的城市名,table1不存在时取table2的城市名,保证城市名不丢失。
方案2:UNION ALL+分组求和写法(全引擎兼容,包括不支持全外连接的MySQL)
如果使用的SQL引擎不支持全外连接,可以先把两表数据纵向合并,再按城市分组求和,兼容性更强:
SELECT column_name, SUM(number_val) AS number_P FROM ( SELECT column_name1 AS column_name, number_P1 AS number_val FROM table1 UNION ALL SELECT column_name2 AS column_name, number_P2 AS number_val FROM table2 ) AS city_combined GROUP BY column_name;
逻辑说明:
- 先通过
UNION ALL把两张表的「城市名-人口数」数据拼成一张统一的临时表,不会丢失任何一张表的城市记录 - 再按城市名分组,用
SUM函数直接累加对应人口数,不需要额外处理空值,写法更简洁,适配所有SQL运行环境。
两种写法执行后都能得到预期输出:
| column_name | number_P |
|---|---|
| PARIS | 110 |
| LISBOA | 20 |
| RIO | 30 |
| NEW YORK | 300 |
内容的提问来源于stack exchange,提问作者valentim.kodak
相关产品推荐
相关产品推荐

