MySQL去重复查询保留最后一条
当我们在MySQL数据库中进行查询时,有时候我们希望去除重复的数据,只保留最后一条。这种需求在实际开发中非常常见,本文将介绍如何使用MySQL来实现该功能。
场景描述
假设我们有一个名为students
的表,存储了学生的信息。该表的结构如下:
id | name | age |
---|---|---|
1 | Alice | 18 |
2 | Bob | 20 |
3 | Carol | 19 |
4 | Alice | 20 |
5 | David | 22 |
6 | Carol | 21 |
我们希望查询出不重复的学生名字,并且只保留每个学生的最后一条记录。
方法一:使用子查询
我们可以使用子查询的方式来实现该功能。首先,我们可以通过子查询得到每个学生的最大id值,然后再根据这些id值查询出对应的记录。
SELECT id, name, age
FROM students
WHERE id IN (
SELECT MAX(id)
FROM students
GROUP BY name
)
上述查询语句中,子查询SELECT MAX(id) FROM students GROUP BY name
返回每个学生的最大id值,然后通过外部查询获取对应的记录。
执行以上查询语句,将得到以下结果:
id | name | age |
---|---|---|
4 | Alice | 20 |
2 | Bob | 20 |
6 | Carol | 21 |
5 | David | 22 |
方法二:使用JOIN
除了使用子查询,我们还可以使用JOIN操作来实现该功能。我们可以将表本身连接一次,并通过条件限制保留每个学生的最后一条记录。
SELECT s1.id, s1.name, s1.age
FROM students s1
LEFT JOIN students s2 ON s1.name = s2.name AND s1.id < s2.id
WHERE s2.id IS NULL
上述查询语句中,我们使用了自连接操作,将表连接一次。通过条件s1.name = s2.name AND s1.id < s2.id
,我们保证了只有最后一条记录的s2.id
为NULL。这样就实现了去重复并保留最后一条记录的效果。
执行以上查询语句,将得到以下结果:
id | name | age |
---|---|---|
4 | Alice | 20 |
2 | Bob | 20 |
6 | Carol | 21 |
5 | David | 22 |
性能对比
为了比较两种方法的性能差异,我们可以使用EXPLAIN
关键字查看查询计划,并观察执行时间。
EXPLAIN SELECT id, name, age
FROM students
WHERE id IN (
SELECT MAX(id)
FROM students
GROUP BY name
)
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | PRIMARY | students | index | PRIMARY | 4 | 6 | 100.00 | Using where | |||
2 | SUBQUERY | students | index | PRIMARY | 4 | 6 | 100.00 | Using index |
EXPLAIN SELECT s1.id, s1.name, s1.age
FROM students s1
LEFT JOIN students s2 ON s1.name = s2.name AND s1.id < s2.id
WHERE s2.id IS NULL
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | s1 | ALL | 6 | 100.00 | Using where | |||||
1 | SIMPLE | s2 | eq |