SQL中DISTINCT与GROUP BY的用法及多表联查计数错误解决
嘿,这两个都是SQL开发里超常见的问题,我来给你拆解清楚~
1. 如何在SQL中使用DISTINCT和GROUP BY?
先说说DISTINCT
它的核心作用就是帮你去掉查询结果里的重复行,直接放在SELECT关键字后面就行:
- 单字段去重:比如想查用户表中所有不重复的城市,写法很简单:
SELECT DISTINCT city FROM users;
- 多字段组合去重:只有当你指定的所有字段值完全一致时,才会被视为重复行剔除,比如按城市+年龄组合去重:
SELECT DISTINCT city, age FROM users;
再看GROUP BY
它是用来对数据分组的,通常得和聚合函数(比如COUNT()、SUM()、AVG())搭配使用,才能实现分组统计的需求:
- 基础分组统计:比如统计每个城市的用户数量:
SELECT city, COUNT(*) AS user_count FROM users GROUP BY city;
- 多字段分组:如果要按「城市+年龄」的组合来统计人数,就把两个字段都放到
GROUP BY里:
SELECT city, age, COUNT(*) AS user_count FROM users GROUP BY city, age;
两者的核心区别
DISTINCT只是单纯做去重操作,没法配合聚合函数做统计;GROUP BY是先分组,再对每个组做各类统计计算。- 如果你只需要获取去重后的字段值,用
DISTINCT更简洁;要是需要分组统计数据,那必须用GROUP BY。
2. 关联多表时COUNT结果偏大,加DISTINCT报错的解决方法
这种情况十有八九是因为bills和details_bills是一对多的关系——一条账单对应多条明细,关联查询后一条账单会被重复展示好几次,COUNT的时候自然就把重复的行也算进去了。你说加DISTINCT报错,应该是写法不对,正确的姿势是把DISTINCT放到COUNT()的括号里,针对账单的唯一标识(比如Id)去重计数。
正确的修改示例
假设你原来的查询是这样的:
SELECT bills.Id, COUNT(bills.Id) AS bill_counts -- 这里因为关联明细,会重复计数 FROM bills JOIN details_bills ON bills.Id = details_bills.bill_id GROUP BY bills.Id;
改成下面这样就可以得到正确数值了:
SELECT bills.Id, COUNT(DISTINCT bills.Id) AS bill_counts -- 只统计唯一的账单Id FROM bills JOIN details_bills ON bills.Id = details_bills.bill_id GROUP BY bills.Id;
更高效的替代写法
如果你的查询不需要用到details_bills里的其他字段,其实可以不用JOIN,改用EXISTS来判断,这样能避免产生重复行,性能也更好:
SELECT Id, COUNT(*) AS bill_counts FROM bills WHERE EXISTS ( SELECT 1 FROM details_bills WHERE details_bills.bill_id = bills.Id ) GROUP BY Id;
要是你只是想统计所有账单的总数(不管有没有明细),那更简单,直接查bills表就行,完全不用关联:
SELECT COUNT(*) AS bill_counts FROM bills;
内容的提问来源于stack exchange,提问作者pimienta
相关产品推荐
相关产品推荐

