You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

MySQL技术问询:如何删除字段重复项及带前缀的对应重复行

没问题,这两个关于MySQL删除重复记录的问题我经常遇到,给你详细拆解一下:

1. 在MySQL中如何删除某一字段的重复记录?

核心需求一般是保留重复组里的某一条记录(比如最早/最晚创建的),删掉其他重复项,这里有两种常用方案,适配不同MySQL版本:

  • 方案一:DELETE自连接(兼容所有MySQL版本)
    假设你的表叫your_table,要去重的字段是target_column,我们要保留每个重复组里id最小的那条(你也可以换成其他唯一标识字段,比如创建时间create_time):
DELETE t1 FROM your_table t1
JOIN your_table t2 
ON t1.target_column = t2.target_column 
AND t1.id > t2.id;

简单说就是:通过自连接找到所有和其他行字段值相同,但id更大的行,然后删掉这些行——这样就留下了每个重复组里id最小的那条。如果想保留id最大的,把t1.id > t2.id改成t1.id < t2.id就行。

  • 方案二:窗口函数(MySQL 8.0+适用)
    如果你的MySQL是8.0及以上版本,用窗口函数会更直观,逻辑清晰不容易出错:
DELETE FROM your_table
WHERE id IN (
    SELECT id FROM (
        SELECT 
            id,
            ROW_NUMBER() OVER (PARTITION BY target_column ORDER BY id) AS rn
        FROM your_table
    ) AS temp
    WHERE rn > 1
);

这里用ROW_NUMBER()给每个target_column相同的行分组编号,编号大于1的就是重复项,直接删掉就行。注意必须套一层子查询,因为MySQL不允许在DELETE语句里直接引用正在修改的表,临时表刚好规避这个问题。

2. 在MySQL中是否可以删除与另一行字段带有指定前缀的对应重复行?

当然可以!关键是先明确“对应重复”的逻辑,我给你两种最常见的场景举例:

场景一:删除前缀相同且字段值完全重复的行

比如你的表有个value字段,前缀是pre_,要删掉所有valuepre_开头且重复的行,只保留每个值的一条:
直接在上面的去重逻辑里加个前缀过滤条件就行:

-- 用DELETE自连接的方式
DELETE t1 FROM your_table t1
JOIN your_table t2 
ON t1.value = t2.value 
AND t1.id > t2.id
WHERE t1.value LIKE 'pre_%';

或者用窗口函数的版本:

DELETE FROM your_table
WHERE id IN (
    SELECT id FROM (
        SELECT 
            id,
            ROW_NUMBER() OVER (PARTITION BY value ORDER BY id) AS rn
        FROM your_table
        WHERE value LIKE 'pre_%'
    ) AS temp
    WHERE rn > 1
);

这样就只会处理带pre_前缀的行,不会影响其他前缀的记录。

场景二:删除去掉前缀后内容重复的行

比如value字段是pre_applepre_appleother_apple,你要删的是去掉pre_前缀后内容重复的行(也就是apple重复的那些pre_开头的行),这时候需要先提取前缀后的内容:

  • 如果前缀是固定长度的(比如pre_是4个字符),用SUBSTRING()
DELETE t1 FROM your_table t1
JOIN your_table t2 
ON SUBSTRING(t1.value, 5) = SUBSTRING(t2.value, 5)  -- 从第5个字符开始取,去掉pre_
AND t1.id > t2.id
WHERE t1.value LIKE 'pre_%';
  • 如果前缀是不固定长度但有分隔符(比如_),用SUBSTRING_INDEX()取分隔符后面的内容:
DELETE t1 FROM your_table t1
JOIN your_table t2 
ON SUBSTRING_INDEX(t1.value, '_', -1) = SUBSTRING_INDEX(t2.value, '_', -1)  -- 取_后面的部分
AND t1.id > t2.id
WHERE t1.value LIKE 'pre_%';

这样就能精准删掉符合要求的重复行啦。

内容的提问来源于stack exchange,提问作者d-_-b

火山引擎 最新活动