如何在MariaDB中删除row_number<>1的重复记录?
在MariaDB中删除重复记录保留每组第一条的正确方法
你的写法存在几个核心问题:
- 第一个
EXISTS子查询只要表内有记录就返回true,导致所有行被删除 - 窗口函数的别名(如
row_number)无法直接在子查询的WHERE子句中使用——窗口函数的计算逻辑在WHERE过滤之后执行 - 第三个写法存在语法错误,单个
DELETE语句不能包含两个WHERE子句
以下是两种可行的解决方案:
方法一:使用CTE(MariaDB 10.2及以上版本支持)
通过CTE为每条记录生成行号,再通过主键/唯一标识关联原表,删除行号大于1的重复记录:
WITH ranked_rows AS ( SELECT id, -- 替换为你的表的主键或唯一标识列 ROW_NUMBER() OVER ( PARTITION BY 列1, 列2 -- 替换为用于分组去重的列名列表 ORDER BY 排序列1, 排序列2 -- 替换为用于确定保留哪条记录的排序列 ) AS row_num FROM TABLE_NAME ) DELETE FROM TABLE_NAME WHERE id IN (SELECT id FROM ranked_rows WHERE row_num > 1);
方法二:使用子查询关联(兼容低版本MariaDB)
如果你的MariaDB版本不支持CTE,可以用子查询关联的方式实现:
DELETE t1 FROM TABLE_NAME t1 JOIN ( SELECT id, ROW_NUMBER() OVER ( PARTITION BY 列1, 列2 ORDER BY 排序列1, 排序列2 ) AS row_num FROM TABLE_NAME ) t2 ON t1.id = t2.id WHERE t2.row_num > 1;
注意事项
- 替换代码中的
TABLE_NAME、分组列、排序列、主键列id为你实际的表和列名 - 执行删除操作前务必备份数据,避免误删无法恢复
- 如果表没有主键或唯一标识,可以用所有列的组合关联,但效率较低,建议优先为表添加唯一键
内容的提问来源于stack exchange,提问作者postgreshelp
相关产品推荐
相关产品推荐

