保留表中重复记录中第一行数据,删除其他数据

本文详细介绍了SQL中ROW_NUMBER()函数的使用方法,特别是与PARTITION BY结合时如何实现数据排序与去重。通过具体实例展示了如何在数据处理中灵活运用该函数,提高数据查询效率。

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

CREATE TABLE #TableA
(
 Id int
 ,Name nvarchar(20)
)
GO
INSERT INTO #TableA VALUES(1,'222')
INSERT INTO #TableA VALUES(2,'2323')
INSERT INTO #TableA VALUES(3,'DSF')
INSERT INTO #TableA VALUES(4,'234')
INSERT INTO #TableA VALUES(5,'SDFSF')
INSERT INTO #TableA VALUES(6,'222')
INSERT INTO #TableA VALUES(7,'2323')
INSERT INTO #TableA VALUES(8,'2323')

select * from #TableA

delete #TableA from
#TableA,(
select  Id,ROW_NUMBER() over(partition by Name order by Id) as rn from #TableA
) nnt
WHERE #TableA.Id = nnt.Id and nnt.rn > 1


select * from #TableA

 

总结:ROW_NUMBER() partition by联用

 

还有其他方法,以前写过,大脑突然短路,等想起来再补充

<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
发出的红包

打赏作者

感谢一路走过的人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值