mysql的去重distinct和group by的用法

avatar 2021年11月3日18:17:43 评论 1,064 次浏览

本章文章主要是针对mysql的去重的用法,在mysql中不管是查询还是聚合,都会用到去重,虽然mysql里已经有一个去重关键词distinct,但是distinct是用来去重只保留一跳记录,但是如果想返回其他列的内容就不会有了,看下面的例子:

distinct关键词

我们先创建一个表,然后在表中插入数据,利用表中的数据举一些例子:

CREATE TABLE wulaoer (
 id INT(11) PRIMARY KEY AUTO_INCREMENT,
 name VARCHAR(20) NOT NULL,
 grade FLOAT,sex CHAR(2)
)
INSERT INTO wulaoer(name,grade,sex) 
	VALUES ('宋江',40,'男'),
		('卢俊义',100,'男'),
		('皇母娘娘',900,'女'),
		('孙悟空',5000,'男'),
		('贾宝玉',36,'女'),
		('诸葛亮',56,'男'),
		('司马懿',56,'男'),
		('皇母娘娘',900,'男');

下面先使用关键词distinct做去重,在使用distinct之前我们必须要说一点,distinct必须放在查询字段的最前面,不能放到查询字段的中间或者后面。

mysql> select * from wulaoer;
+----+--------------+-------+------+
| id | name         | grade | sex  |
+----+--------------+-------+------+
|  1 | 宋江         |    40 | 男   |
|  2 | 诸葛亮       |   100 | 男   |
|  3 | 皇母娘娘     |   900 | 女   |
|  4 | 孙悟空       |  5000 | 男   |
|  5 | 贾宝玉       |    36 | 女   |
|  6 | 诸葛亮       |    56 | 男   |
|  7 | 司马懿       |    56 | 男   |
|  8 | 皇母娘娘     |   900 | 女   |
+----+--------------+-------+------+
8 rows in set (0.00 sec)

这是表中的内容,下面使用distinct关键词去重grade字段。

mysql> select distinct grade from wulaoer;
+-------+
| grade |
+-------+
|    40 |
|   100 |
|   900 |
|  5000 |
|    36 |
|    56 |
+-------+
6 rows in set (0.00 sec)

这是针对grade列做的去重,如果针对所有列去重,只需要在distinct后增加需要去重的字段即可。

mysql> select distinct name,grade,sex from wulaoer;
+--------------+-------+------+
| name         | grade | sex  |
+--------------+-------+------+
| 宋江         |    40 | 男   |
| 诸葛亮       |   100 | 男   |
| 皇母娘娘     |   900 | 女   |
| 孙悟空       |  5000 | 男   |
| 贾宝玉       |    36 | 女   |
| 诸葛亮       |    56 | 男   |
| 司马懿       |    56 | 男   |
+--------------+-------+------+
7 rows in set (0.00 sec)

因为在列表中我们把name字段的做了重复,如果有一个字段中没有重复,就会打印所有内容,和select * from wulaoer的结果一样,这里就不举例了。

这就是distinct的用法,distinct会对所有字段都起作用,distinct去重是查询的所有字段完全重复的数据,而不是只对distinct后面的单个字段重复的数据,也就是distinct对name,grade,sex都起作用,如果查询多个字段只对一个字段去重distinct是无法实现的。

group by组合

group by的用法和distinct一样,只是在用法有写不通,下面看一下有什么不通,根据单个列去重。

mysql> select name,avg(grade),sex from wulaoer group by name,grade,sex;
+--------------+------------+------+
| name         | avg(grade) | sex  |
+--------------+------------+------+
| 司马懿       |         56 | 男   |
| 孙悟空       |       5000 | 男   |
| 宋江         |         40 | 男   |
| 皇母娘娘     |        900 | 女   |
| 诸葛亮       |         56 | 男   |
| 诸葛亮       |        100 | 男   |
| 贾宝玉       |         36 | 女   |
+--------------+------------+------+

这里有一个问题,如果grade列不是数值,就无法去重来,看下面的例子,去重sex看看。

mysql> select name,grade,sum(sex) from wulaoer group by name,grade,sex;
+--------------+-------+----------+
| name         | grade | sum(sex) |
+--------------+-------+----------+
| 司马懿       |    56 |        0 |
| 孙悟空       |  5000 |        0 |
| 宋江         |    40 |        0 |
| 皇母娘娘     |   900 |        0 |
| 诸葛亮       |    56 |        0 |
| 诸葛亮       |   100 |        0 |
| 贾宝玉       |    36 |        0 |
+--------------+-------+----------+
7 rows in set, 8 warnings (0.01 sec)

group by一般在聚类函数中使用(avg,count,sum等),也可以单独使用,group by也对后面所有的字段均起作用,即使去重查询的所有字段完全重复的数据,而不是只对group by后面连接的单个字段重复的数据,查询的字段与group by后面分组的字段没有限制。

总结:

distinct 是去重查询关键字,而group by 是分组查询 关键字。两者在使用上没有太大的区别,不过在查询速度上不管表中是否增加索引group by的查询比distinct的速度快很多。建议使用group by,这里没有使用数据做例子,以后有时间会写一下。

avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: