查城市列表发现同一个杭州出现了几百次,这是没去重。mysql distinct用法本身简单,坑主要在对多字段的去重规则理解上。
基本写法
SELECT DISTINCT city FROM users;
DISTINCT 紧跟在 SELECT 后面,对后面所有列的整体组合去重,返回的每一行都不重复。
多字段去重:注意是组合去重
最常见的误解:写 SELECT DISTINCT city, age FROM users,以为只对 city 去重。实际是 city 和 age 两个字段拼起来都不重复才算一条,杭州加 25 岁和杭州加 30 岁会各出一行。想只按城市去重,就只查 city 一列,或者用 group by:SELECT city FROM users GROUP BY city,两种写法在多数情况下结果一样。真要按某列去重又想带上其他列,一般用 GROUP BY 加聚合函数取值,别指望 DISTINCT 帮你挑留哪一行。
去重统计
SELECT COUNT(DISTINCT city) FROM users;
统计有多少个不同城市。多字段写法是 COUNT(DISTINCT city, age),MySQL 里这种写法会把任一列为 NULL 的行排除掉,数据里有空值时结果可能比你预想的少,对不上账先想到这里。
性能和大表建议
DISTINCT 要比较整行,数据量大时比普通查询慢不少。给去重的那几列建联合索引能明显提速;如果去重后还要做聚合,直接用 GROUP BY 更顺。UNION 不带 ALL 时自带去重,两条结果合并想顺路去重也能用它,代价是内部多一步排序。另外 DISTINCT 和 ORDER BY 一起用时,order by 的列最好也在查询列里,不然某些模式下会报错。
一句话收尾:单列去重随便用;多列先想清楚是组合去重还是按某一列去重;统计去重数就上 COUNT(DISTINCT 列名)。不确定结果对不对,拿 limit 几行出来人工核一遍最稳。