如何用PHP删除MySQL表中重复记录仅保留一条?
解决MySQL表中重复手机号记录的删除问题(仅保留每条手机号的任意一条记录)
针对你30多万条企业数据的场景,优先推荐直接用MySQL批量删除的方案,效率远高于PHP循环逐条处理;如果一定要用PHP实现,也可以修正原有代码逻辑。
一、高效SQL批量删除方案(推荐)
直接通过SQL语句一次性删除重复记录,保留每个手机号对应的任意一条(这里以保留id最小的记录为例,若要保留最大的,调整条件即可):
DELETE c1 FROM companies c1 JOIN companies c2 ON c1.phone = c2.phone AND c1.id > c2.id;
说明:
- 这条语句会匹配所有同手机号的记录,删除
id更大的那些,自动保留每个手机号下id最小的那条。 - 如果你的表没有
id主键,可以用其他唯一标识字段替代,比如创建时间created_at,保留最早的记录:DELETE c1 FROM companies c1 JOIN companies c2 ON c1.phone = c2.phone AND c1.created_at > c2.created_at; - 操作前务必先备份数据,也可以先把
DELETE改成SELECT验证要删除的记录是否正确:SELECT c1.* FROM companies c1 JOIN companies c2 ON c1.phone = c2.phone AND c1.id > c2.id;
二、修正后的PHP代码方案
原有代码的问题是直接删除了同手机号的所有记录,需要先指定要保留的那条,再删除其余重复项:
<?php // 查询所有重复手机号,以及每个手机号要保留的最小id(可换成MAX(id)保留最大id) $qry = "SELECT phone, MIN(id) as keep_id FROM companies GROUP BY phone HAVING COUNT(*) > 1"; $result = mysqli_query($dbConn, $qry); while($row = mysqli_fetch_array($result)) { // 转义手机号防止SQL注入,删除该手机号下除保留id外的所有记录 $safe_phone = mysqli_real_escape_string($dbConn, $row['phone']); $qry_del = "DELETE from companies where phone = '{$safe_phone}' AND id != {$row['keep_id']}"; mysqli_query($dbConn, $qry_del); } ?>
注意:
- 必须使用
mysqli_real_escape_string处理手机号,避免SQL注入风险。 - 数据量较大时,PHP循环会产生多次数据库请求,效率远低于批量SQL方案,仅在特殊场景下使用。
内容的提问来源于stack exchange,提问作者Xpert Solutions
相关产品推荐
相关产品推荐

