You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL删除重复记录保留最小ID的SQL语句失效问题咨询

问题分析与修正方案

你的SQL存在的核心问题

你写的删除语句里,第二个子查询犯了一个明显的逻辑错误:

select login_name from (select min(id) from admin_sync_user group by login_name having count(login_name) > 1) as b

内层子查询返回的是每个重复login_name对应的最小id值,但外层却试图去选login_name字段——这个字段根本不存在于内层查询的结果里!这就导致id not in (...)这个条件的集合是空的,相当于这个过滤条件完全没生效,MySQL只会执行前半部分的login_name in (...),把所有有重复login_name的记录全删掉了,而不是保留最小id的那条。

修正后的SQL写法

方法1:修复你原来的SQL结构

把第二个子查询的字段逻辑改对,让它返回正确的最小id集合:

delete from admin_sync_user 
where login_name in (
    select login_name from (
        select login_name from admin_sync_user group by login_name having count(login_name) > 1
    ) as a
) 
and id not in (
    select min_id from (
        select min(id) as min_id from admin_sync_user group by login_name having count(login_name) > 1
    ) as b
);

这里给内层的min(id)起了别名min_id,外层直接获取这些最小id,这样id not in (...)就能正确过滤掉需要保留的记录。

方法2:更高效的自连接写法(推荐)

这种写法逻辑更直观,性能也更好:

delete t1 
from admin_sync_user t1
join admin_sync_user t2 
on t1.login_name = t2.login_name 
and t1.id > t2.id;

它的逻辑是:找到所有和其他记录login_name相同,但id更大的记录,直接删除这些大id的记录,自动保留每个login_name对应的最小id条目。

方法3:MySQL 8.0+ 用窗口函数(最清晰)

如果你的MySQL版本是8.0及以上,用窗口函数可以更直白地标记重复记录:

delete from admin_sync_user
where id in (
    select id from (
        select 
            id,
            row_number() over (partition by login_name order by id asc) as rn
        from admin_sync_user
    ) as t
    where rn > 1
);

row_number()会给每个login_name分组的记录按id升序编号,rn=1就是要保留的最小id记录,rn>1的就是需要删除的重复项。

内容的提问来源于stack exchange,提问作者kate

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:44:47