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