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

如何在无主键/唯一标识时删除数据库中重复字段的单条记录?

解决无主键表中重复记录删除的问题

这个场景太常见了——表没设主键或唯一约束,结果不小心出现了两条完全一样的记录,要删掉其中一条对吧?咱分不同数据库给你唠唠靠谱的操作方法,记得操作前一定要先备份数据,别手滑误删了!

通用核心思路

本质就是先给每条记录生成一个临时的唯一标识,把两条重复的记录区分开,再通过这个标识删除其中一条。不同数据库有不同的快捷方式,往下看:

MySQL/MariaDB 操作方法

  • 快捷法(仅当确定只有两条重复时用):
    直接用LIMIT删一条,数据库会随机选一条删掉(取决于存储引擎的扫描顺序):
    DELETE FROM your_table
    LIMIT 1;
    
  • 稳妥法(适合有更多重复的情况):
    先加个自增临时列当唯一标识,删完再删掉这个列:
    -- 新增自增临时列
    ALTER TABLE your_table ADD temp_id INT AUTO_INCREMENT PRIMARY KEY;
    -- 删除其中一条(比如temp_id为1的那条)
    DELETE FROM your_table WHERE temp_id = 1;
    -- 清理临时列
    ALTER TABLE your_table DROP COLUMN temp_id;
    

SQL Server 操作方法

  • 窗口函数法:
    ROW_NUMBER()给每条记录分配行号,再删掉行号为1的那条:
    WITH cte AS (
        SELECT *,
               -- 这里ORDER BY (SELECT NULL)是随机分配行号,有可排序的列就换成它
               ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn
        FROM your_table
    )
    DELETE FROM cte WHERE rn = 1;
    
  • 临时表中转法:
    先把一条记录存到临时表,清空原表再导回去:
    -- 把一条记录存入临时表
    SELECT TOP 1 * INTO #temp_table FROM your_table;
    -- 清空原表
    TRUNCATE TABLE your_table;
    -- 把临时表的记录导回原表
    INSERT INTO your_table SELECT * FROM #temp_table;
    -- 删除临时表
    DROP TABLE #temp_table;
    

Oracle 操作方法

Oracle自带每行唯一的ROWID,用这个最方便:

  • ROWID法:
    DELETE FROM your_table
    WHERE ROWID IN (
        SELECT ROWID
        FROM (
            SELECT ROWID,
                   ROW_NUMBER() OVER (ORDER BY NULL) AS rn
            FROM your_table
        )
        WHERE rn = 1
    );
    
  • 临时列法(和MySQL类似):
    -- 新增自增临时列
    ALTER TABLE your_table ADD temp_id NUMBER GENERATED ALWAYS AS IDENTITY;
    -- 删除其中一条
    DELETE FROM your_table WHERE temp_id = 1;
    -- 清理临时列
    ALTER TABLE your_table DROP COLUMN temp_id;
    

重要提醒

  1. 操作前务必先备份数据,比如执行SELECT * FROM your_table把记录导出保存,避免误操作。
  2. 处理完之后,建议给表加上主键或唯一约束,从根源上避免重复记录的产生。

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

火山引擎 最新活动