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

MySQL中删除无唯一标识符的表内重复数据

MySQL中删除无唯一标识符的表内重复数据

嘿,我懂你现在的困扰——用MySQL Workbench 8.0.36学SQL的时候,发现Employee表里有重复数据,就像EmpID=1的Arjun,信息被录入了两次,而且原表还没有唯一标识符来区分这些重复行(你提到的RowNum只是临时用的,原表没有这个字段)。先把你的表结构和数据明确一下(去掉临时的RowNum):

EmpIDEmpnameGenderSalaryCity
1ArjunM75000Pune
1ArjunM75000Pune
2EkadantaM125000Bangalore
3LalitaF150000Mathura
4MadhavM250000Delhi
5VishakhaF120000Mathura

针对这种没有唯一主键的重复数据删除,因为你用的是MySQL 8.0+版本,我推荐两种实用的方法:

方法一:用窗口函数标记重复行(最稳妥)

MySQL 8.0开始支持窗口函数,我们可以用ROW_NUMBER()给每组重复数据分配行号,然后删除行号大于1的记录(只保留每组的第一条):

-- 先创建一个临时的带行号的数据集
WITH ranked_employees AS (
    SELECT *,
           -- 按所有字段分组,标记重复行的序号
           ROW_NUMBER() OVER (PARTITION BY EmpID, Empname, Gender, Salary, City ORDER BY (SELECT NULL)) AS rn
    FROM Employee
)
-- 删除行号大于1的重复记录
DELETE FROM Employee
WHERE (EmpID, Empname, Gender, Salary, City) IN (
    SELECT EmpID, Empname, Gender, Salary, City
    FROM ranked_employees
    WHERE rn > 1
);

这里解释下:

  • PARTITION BY后面的字段是判断重复的依据——只要这些字段完全相同,就视为重复行
  • ORDER BY (SELECT NULL)是因为我们不需要特意保留某一条(比如最早/最晚录入的),如果有时间戳之类的字段,可以换成那个字段来指定保留哪条

方法二:用自连接删除重复行

如果你不想用CTE(公共表表达式),也可以通过自连接的方式,利用MySQL隐式的ROWID来区分不同行:

DELETE e1
FROM Employee e1
JOIN Employee e2
-- 匹配所有重复字段
ON e1.EmpID = e2.EmpID 
AND e1.Empname = e2.Empname 
AND e1.Gender = e2.Gender 
AND e1.Salary = e2.Salary 
AND e1.City = e2.City
-- 保留ROWID更小的那条,删除更大的
AND e1.ROWID > e2.ROWID;

注意:ROWID是MySQL内部的行标识符,不同存储引擎(比如InnoDB/MyISAM)的实现可能有差异,所以方法一更通用。

后续预防建议

为了避免以后再出现这种重复数据,最好给表加上唯一约束或者主键:

-- 如果EmpID应该是唯一的,直接设为主键
ALTER TABLE Employee ADD PRIMARY KEY (EmpID);

-- 如果EmpID可能重复(比如同个员工多条记录),可以创建复合唯一索引
CREATE UNIQUE INDEX idx_employee_unique ON Employee (EmpID, Empname, Gender, Salary, City);

备注:内容来源于stack exchange,提问作者Rakesh Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 11:28:13