




















Mysql查询:每个重复数据,只显示一条,通过使用 min(id)实现是一个非常经典和高效的方法!这通常用于在有自增主键(如 id)的表中,从重复数据中保留“最老”或“最早”插入的那一条记录。
下面我为您详细介绍如何使用 MIN(id) 来实现“每个重复数据只显示一条”。
假设我们有一个用户表 users,结构如下:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50),
email VARCHAR(100),
age INT
);
表中有一些重复的 email 数据:
| id | name | age | |
|---|---|---|---|
| 1 | Alice | alice@email.com | 25 |
| 2 | Bob | bob@email.com | 30 |
| 3 | Alice | alice@email.com | 26 |
| 4 | Carol | carol@email.com | 28 |
| 5 | Bob | bob@email.com | 32 |
我们希望根据 email 字段去重,保留每个 email 对应的 id 最小的那条记录。
MIN(id) + GROUP BY(推荐用于查询)如果您只是想查询去重后的数据(不修改原表),可以使用:
SELECT MIN(id) AS id, name, email, age
FROM users
GROUP BY email;
结果:
| id | name | age | |
|---|---|---|---|
| 1 | Alice | alice@email.com | 25 |
| 2 | Bob | bob@email.com | 30 |
| 4 | Carol | carol@email.com | 28 |
注意:这里有一个重要细节!虽然我们
GROUP BY email,但name和age并不在GROUP BY子句中。在 MySQL 的宽松模式下,这会返回每个分组中第一条遇到的记录的name和age。由于我们使用了MIN(id),通常第一条就是id最小的那条,所以结果是正确的。但在 SQL 严格模式(如
ONLY_FULL_GROUP_BY)下,这种写法会报错。更严谨的写法是结合子查询。
为了确保结果的准确性和兼容性,推荐使用子查询先找出每个 email 对应的最小 id,然后再关联查询完整数据:
SELECT u.id, u.name, u.email, u.age
FROM users u
INNER JOIN (
SELECT email, MIN(id) AS min_id
FROM users
GROUP BY email
) t ON u.email = t.email AND u.id = t.min_id;
结果(同上):
| id | name | age | |
|---|---|---|---|
| 1 | Alice | alice@email.com | 25 |
| 2 | Bob | bob@email.com | 30 |
| 4 | Carol | carol@email.com | 28 |
优点:
如果您想永久删除重复数据,只保留 id 最小的那条,可以使用:
DELETE u1 FROM users u1
INNER JOIN users u2
WHERE u1.email = u2.email
AND u1.id > u2.id;
这条语句的逻辑是:对于每一对具有相同 email 的记录,如果 u1 的 id 大于 u2 的 id,就删除 u1。最终只保留 id 最小的那条。
MIN(id) 是一个非常实用的技巧,它利用了自增主键的特性来确定“第一条”记录。min(id) 实现”完全正确,并且是数据库去重的最佳实践之一。👍此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。