MySQL关联查询结果异常:需基于表A统计且过滤表B字段
问题分析与解决方案
你的SQL语句出现重复统计的核心原因:
- 表B中同一个
city_code对应多条user_name="xyz"的记录,和表A关联后,A的单条记录会被重复匹配多次,导致count(a.city_code)把这些重复行全部计入统计,结果自然远大于A的实际记录数。 - 你用了
Left Join但后续加了where b.user_name = "xyz",这会把Left Join自动转换成Inner Join——因为Left Join原本会保留A的所有记录,但where过滤B的字段后,会直接剔除B中无匹配的A记录。
下面是几种可行的解决办法:
方法一:用distinct去重统计
直接在count中加入distinct,让数据库只统计A中唯一的city_code数量:
Select a.status as status, count(distinct a.city_code) as count from A a Join B b on a.city_code = b.city_code where b.user_name = "xyz" group by a.status
这里把Left Join改成Join(即Inner Join)更准确,因为你的需求是只统计满足B过滤条件的A记录,不需要保留无匹配的A数据。
方法二:先过滤去重表B再关联
先在子查询里把表B中符合user_name="xyz"的city_code去重,再和表A关联,这样关联后不会产生重复行,直接count即可:
Select a.status as status, count(a.city_code) as count from A a Join ( select distinct city_code from B where user_name = "xyz" ) b on a.city_code = b.city_code group by a.status
这种方法性能更优,尤其是表B数据量大时,子查询先过滤去重能减少后续关联的数据量。
方法三:保留A中无匹配的记录(可选)
如果需要统计每个status下满足B条件的A记录数,同时保留那些没有匹配B的status(此时count为0),可以用Left Join关联去重后的B子查询:
Select a.status as status, count(b.city_code) as count from A a Left Join ( select distinct city_code from B where user_name = "xyz" ) b on a.city_code = b.city_code group by a.status
内容的提问来源于stack exchange,提问作者Faheem Ilahi
相关产品推荐
相关产品推荐

