在使用 MySQL 时,有时需要查询出某个字段不重复的记录,这时可以使用 MySQL 提供的 distinct
这个关键字来过滤重复的记录[1]
。
语法格式:
select
distinct expression[,expression...]
from
tables
[where conditions];
01 distinct 的用法
例如,我们有表如下:
mysql> select * from user;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | taylor | pass123 |
| 2 | spring | pass456 |
| 3 | Yahto | taf23 |
| 4 | Lillie | flowwer |
| 5 | Lia | wherend |
| 6 | Lia2 | wherend |
| 7 | Lia3 | wherend |
| 8 | Lia4 | wherend |
+----+----------+----------+
1.1 简单的用法
用 distinct
返回不重复的密码:
mysql> select distinct password from user;
+----------+
| password |
+----------+
| pass123 |
| pass456 |
| taf23 |
| flowwer |
| wherend | -- 去除了其他 3 个重复字段
+----------+
但是,这样只能查出不同的密码,不能查出密码对应的用户 id 或用户名。
实际开发中,我们往往用 distinct
来返回不重复字段的条数(count(distinct id)
),就是因为 distinct
只能返回它的目标字段,而无法返回其他字段。
1.2 distinct 的注意事项
从最前面 distinct
的语法格式可以看出[2]
:
distinct
要放在所有字段的前面- 如果去重的字段大于一个,则会进行组合去重,只有多个字段组合起来相同时才会被去重
mysql> select distinct username, password from user;
+----------+----------+
| username | password |
+----------+----------+
| taylor | pass123 |
| spring | pass456 |
| Yahto | taf23 |
| Lillie | flowwer |
| Lia | wherend | -- 由于 username 不同,故 password 相同也不能去重
| Lia2 | wherend |
| Lia3 | wherend |
| Lia4 | wherend |
+----------+----------+
02 可能遇到的其他用法
2.1 错误使用 distinct(c)
不知道你们有没有遇到过这样的例子:
要求查出所有用户,并根据手机号过滤重复记录。。。
可能一不小心就会遇到这样子的查询语句(这里用过滤相同密码来试验):
mysql> select distinct(password), username from user;
+----------+----------+
| password | username |
+----------+----------+
| pass123 | taylor |
| pass456 | spring |
| taf23 | Yahto |
| flowwer | Lillie |
| wherend | Lia | -- 其实还是过滤 password+username
| wherend | Lia2 |
| wherend | Lia3 |
| wherend | Lia4 |
+----------+----------+
distinct(column_name)
并没有按照函数操作那样,仅对括号内的列进行去重,而是依旧对 distinct
后面的所有列进行组合去重。(其实这里 distinct
也只能放在最前面,放到后面就会报错了)
2.2 计数 count(distinct c)
计数方式的两种情况。
第一种,计算指定字段的出现次数,可以直接用 count
:
mysql> select count(username) AS total
-> from user
-> where password = 'wherend';
+-------+
| total |
+-------+
| 4 |
+-------+
第二种,计算所有字段的出现次数,先根据 password 分组,然后计数时根据不同的 username 来计算(如果用户名一样,则认为是相同的)
mysql> select
-> password, count(distinct username) as num
-> from
-> user
-> group by
-> password;
+----------+-----+
| password | num |
+----------+-----+
| flowwer | 1 |
| pass123 | 1 |
| pass456 | 1 |
| taf23 | 1 |
| wherend | 4 |
+----------+-----+
总结
- 因为
distinct
只能返回他的目标字段,而无法返回其他字段,故一般用来计算不重复字段的条数(须先分组)
mysql> select
-> password, count(distinct id) AS num
-> from
-> user
-> group by password;
+----------+-----+
| password | num |
+----------+-----+
| flowwer | 4 |
| pass123 | 1 |
+----------+-----+
- 单纯去除重复,以便获取去重后的集合
mysql> select distinct password from user;
+----------+
| password |
+----------+
| pass123 |
| pass456 |
+----------+
完。
REFERENCES
[1] 失落的黎明. mysql 中去重 distinct 用法: https://www.cnblogs.com/shiluoliming/p/6604407.html
[2] 有梦想的攻城狮. mysql 中的 distinct 的用法: https://blog.csdn.net/zhangzehai2234/article/details/88361586