SQL中删除重复的行(重复数据),只保留一行

本文介绍两种在SQL中处理重复数据的方法:一是通过T-SQL编程分配行号并删除重复记录;二是利用ETL过程创建不含重复项的新表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SQL中删除重复的行(重复数据),只保留一行
方法一:使用在T-SQL的编程中
分配一个列号码,以COL1,COL2组合来分区排序,删除DATABASE重复的行(重复数据),只保留一行
// COL1,COL2是数据库DATABASE的栏位
delete a from (select COL1,COL2,row_number() over (partition by COL1,COL2 order by COL1) as rn from DATABASE) a where a.rn>1
方法二:使用在ETL中
select distant into,这种方法借助一个新的table,把不重复的结果集转移到新table中
SELECT distinct Col1, Col2 INTO NoDups
FROM Dup1;
select * from NoDups
<think>我们使用ROWID来删除重复数据保留一行(例如保留ROWID最小的那一行) 步骤: 1. 先找出重复数据中要保留的那一行(通常是ROWID最小的或最大的) 2. 删除那些重复的且ROWID不在保留列表中的 方法1:使用子查询 ```sql DELETE FROM your_table WHERE ROWID NOT IN ( SELECT MIN(ROWID) -- 或MAX(ROWID),根据需求保留 FROM your_table GROUP BY column1, column2 -- 按重复字段分组 ); ``` 方法2:使用ROW_NUMBER()窗口函数(适用于复杂条件) ```sql DELETE FROM your_table WHERE ROWID IN ( SELECT rid FROM ( SELECT ROWID AS rid, ROW_NUMBER() OVER (PARTITION BY column1, column2 ORDER BY ROWID) AS rn FROM your_table ) WHERE rn > 1 -- 保留第一个(rn=1),删除rn>1的重复 ); ``` ### 注意事项: 1. **备份**:删除前务必备份数据 2. **事务**:在事务中执(BEGIN ... DELETE ... COMMIT/ROLLBACK)以便回滚 3. **性能**:大表可考虑分批删除或创建临时表 §§相关问题§§ 1. 如何保留重复数据中最新的一条记录(按时间戳)? 2. 删除重复数据时如何避免锁表导致性能问题? 3. 除了ROWID,Oracle中还有哪些方法可以唯一标识一行? 4. 如何在不删除的情况下给重复数据打标记? 5. 使用ROW_NUMBER()删除重复数据与使用GROUP BY删除有何优劣?</think>在 Oracle 中删除重复数据保留一行,推荐使用 `ROWID` 结合分组查询的高效方法: ### 解决方案 ```sql DELETE FROM your_table WHERE ROWID NOT IN ( SELECT MIN(ROWID) -- 保留每组重复数据中ROWID最小的 FROM your_table GROUP BY column1, column2, column3 -- 指定判断重复的列 ); ``` ### 关键步骤说明: 1. **核心逻辑** - 子查询:通过 `GROUP BY` 对重复字段分组,用 `MIN(ROWID)` 定位每组要保留 - 主查询:删除所有不在保留列表中的 `ROWID` 2. **操作流程**: ```sql -- 1. 先验证查询(安全确认) SELECT * FROM your_table WHERE ROWID NOT IN ( SELECT MIN(ROWID) FROM your_table GROUP BY duplicate_col1, duplicate_col2 ); -- 2. 执删除(事务中操作) BEGIN DELETE FROM orders WHERE ROWID NOT IN ( SELECT MIN(ROWID) FROM orders GROUP BY customer_id, product_id ); COMMIT; END; ``` 3. **高级场景处理**: - **保留最新数据**(按时间戳): ```sql DELETE FROM log_table WHERE ROWID NOT IN ( SELECT MAX(ROWID) KEEP (DENSE_RANK FIRST ORDER BY create_time DESC) FROM log_table GROUP BY user_id, session_id ); ``` - **带条件删除**(如保留有效记录): ```sql DELETE FROM employees WHERE ROWID NOT IN ( SELECT MIN(ROWID) FROM employees WHERE status = 'ACTIVE' -- 只处理有效记录 GROUP BY employee_code ); ``` ### 注意事项 1. **必须备份**:操作前执 `CREATE TABLE table_bak AS SELECT * FROM your_table` 2. **事务控制**:使用 `BEGIN...COMMIT` 确保可回滚 3. **性能优化**:大表添加 `WHERE rownum <= 10000` 分批删除
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值