报表里城市一列重复了十几行,第一反应就是加个 distinct。它写在 select 后面,作用是把结果里重复的行去掉,只留一份。
单列去重和多列去重
select distinct city from users;select distinct city, district from users;第一句好理解,城市去重。第二句要注意:distinct 不是只对 city 去重,而是对 city 加 district 的组合去重,同一个城市的不同区算不同组合,都会保留。很多人以为 distinct 写在第一列就只管第一列,结果数据还是重的,就是这里没搞清。
和 count 搭配的口径
distinct用法里最容易混的是和 count 的搭配。
select count(distinct city) from users;这是统计去重后的城市数量。注意括号位置,把多个列都塞进同一个括号里,在 MySQL 会直接报错,想按组合计数,得先把两列拼起来再数,或者套一层子查询。
几个容易踩的点
- distinct 作用于整个 select 列表,不是紧跟它的那一列
- 带它的查询配合 order by 时,排序字段最好也在 select 列表里,否则部分版本会报错
- null 也算一种取值,去重后 null 只保留一行
- 去重需要排序或哈希,数据量大时先 where 过滤再 distinct,别全表去完再筛
相近的写法还有 group by,单列去重两者结果一样,但 group by 是配合聚合函数用的,语义不同。distinct用法就这几条规则,口径拿不准时先拿小表跑一遍对数,比猜快得多。