MySql删除重复数据并保留一条

本文介绍了在MySQL中删除用户message表中重复消息的方法,通过分组查询找出每个用户的最新消息,然后使用LEFTJOIN筛选出需要删除的旧记录,确保效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近期遇到需要删除一张表中重复数据的需求,解决思路如下:

先分组查询,得到每组中的一条记录,这些记录就是需要保留的记录。然后在此基础上使用left join 查询,得到需要删除的数据。最后删除这些数据。下面举例说明:

假设需要操作的表为 usermessage,结构如下:

 该表记录了用户的消息,表内容如下:

一共两个用户,每个用户都有4条消息,每条消息后面都有时间戳(updatetime)。

我们的需求是:删除该表中重复记录,每个用户只保留最近的一条消息。

按解决思路,首先分组查询出每个用户的最近(updatetime最大)的一条消息。

SELECT userId, message, max(updatetime) updatetime FROM usermessage group by userId

 结果如下:

 然后在此基础上查询需要删除的数据,

select * from usermessage a 
   left join (SELECT userId, message, max(updatetime) updatetime 
                 FROM usermessage group by userId) b 
   on a.userid = b.userid and a.updatetime = b.updatetime  
where b.updatetime is null;

 结果如下:

对比原表可以看出,这就是需要删除的数据。

最后,我们来删除这些数据。注意:因为这里使用了left join ,所以还不能直接将select 换为 delete,会报错:

而应该用下面的代码:

delete a from usermessage a 
   left join (SELECT userId, message, max(updatetime) updatetime 
              FROM usermessage group by userId) b 
   on a.userid = b.userid and a.updatetime = b.updatetime  
where b.updatetime is null;

 执行结果如下:

可以看到删除了6条记录,这正是我们需要的结果,这时你查询原表,就发现任务完成了。

 下面将该表的建表及测试数据插入sql 贴出来,方便大家验证:

DROP TABLE IF EXISTS `usermessage`;
CREATE TABLE `usermessage`  (
  `userId` int(11) NOT NULL COMMENT '用户ID',
  `message` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '消息',
  `updatetime` bigint(20) NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`userId`, `updatetime`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of usermessage
-- ----------------------------
INSERT INTO `usermessage` VALUES (1001, '我来了', 1685234289123);
INSERT INTO `usermessage` VALUES (1001, '我是谁', 1692142049544);
INSERT INTO `usermessage` VALUES (1001, '我还是我', 1692240089846);
INSERT INTO `usermessage` VALUES (1001, '我在这里', 1692240189247);
INSERT INTO `usermessage` VALUES (1002, '你在吗?', 1646240084562);
INSERT INTO `usermessage` VALUES (1002, '你是谁', 1691142389469);
INSERT INTO `usermessage` VALUES (1002, '你还是你', 1692042249856);
INSERT INTO `usermessage` VALUES (1002, '你在哪里', 1692140439436);

补充说明:有一些文章中介绍使用 in 的方式来筛选,实测发现效率很低,使用left join是效率比较高的一种方式。

参考文献:

【mysql】mysql删除重复记录并且只保留一条_mysql删除完全重复数据只保留一条_千g的博客-CSDN博客
mysql delete from ... left join .. on .._mysql delete from join_torpidcat的博客-CSDN博客
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值