您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Oracle中怎么利用row_number()over()方式解决插入数据时重复键
## 引言
在Oracle数据库开发中,我们经常会遇到需要向表中插入数据时处理重复键的问题。传统方法如使用MERGE语句或先查询后插入的方式虽然可行,但效率较低且代码复杂。本文将详细介绍如何利用`row_number() over()`分析函数高效解决这一问题。
## 一、重复键问题的常见场景
### 1.1 业务数据去重
当从外部系统导入数据时,经常需要避免主键或唯一键冲突:
```sql
-- 典型报错示例
ORA-00001: 违反唯一约束条件 (SCOTT.PK_EMP)
在不同环境间迁移数据时,需要处理目标表已存在部分数据的情况。
MERGE INTO target_table t
USING source_table s
ON (t.id = s.id)
WHEN NOT MATCHED THEN
INSERT VALUES(s.col1, s.col2...);
缺点:语法复杂,对大批量数据性能一般
DELETE FROM target_table WHERE id IN (SELECT id FROM source_table);
INSERT INTO target_table SELECT * FROM source_table;
缺点:存在事务风险,可能造成数据丢失
row_number() over()
是Oracle的分析函数,可为结果集的每一行分配唯一序号:
SELECT
id,
name,
row_number() OVER(PARTITION BY id ORDER BY create_time DESC) rn
FROM source_data
INSERT INTO target_table(id, name, create_time)
SELECT id, name, create_time
FROM (
SELECT
id,
name,
create_time,
row_number() OVER(PARTITION BY id ORDER BY create_time DESC) rn
FROM source_data
)
WHERE rn = 1
AND NOT EXISTS (
SELECT 1 FROM target_table t
WHERE t.id = source_data.id
);
-- 假设唯一键由(col1,col2)组成
INSERT INTO target_table(col1, col2, col3)
SELECT col1, col2, col3
FROM (
SELECT
col1,
col2,
col3,
row_number() OVER(PARTITION BY col1, col2 ORDER BY version DESC) rn
FROM staging_table
)
WHERE rn = 1;
PARTITION BY
子句包含所有唯一键列-- 根据业务需求选择排序字段
row_number() OVER(PARTITION BY id ORDER BY
CASE WHEN source_system = 'ERP' THEN 0 ELSE 1 END,
update_date DESC)
-- 启用并行查询
INSERT /*+ PARALLEL(4) */ INTO target_table...
SELECT /*+ PARALLEL(4) */ ... FROM source_data
方案 | 优点 | 缺点 |
---|---|---|
row_number() over() | 单次扫描、代码简洁 | 需要理解分析函数 |
MERGE | 原子性操作 | 语法复杂,性能中等 |
先删后插 | 逻辑简单 | 存在数据丢失风险 |
-- 每天同步订单数据,保留最新版本
INSERT INTO dw_orders
SELECT order_id, user_id, status, update_time
FROM (
SELECT
order_id,
user_id,
status,
update_time,
row_number() OVER(PARTITION BY order_id ORDER BY update_time DESC) rn
FROM ods_orders
WHERE trunc(update_time) = trunc(SYSDATE)
)
WHERE rn = 1;
-- 合并多个系统的客户数据
CREATE TABLE tmp_customers AS
SELECT customer_id, name, phone, source_system
FROM (
SELECT
customer_id,
name,
phone,
source_system,
row_number() OVER(PARTITION BY customer_id
ORDER BY data_quality_score DESC) rn
FROM (
SELECT * FROM crm_system
UNION ALL
SELECT * FROM erp_system
)
)
WHERE rn = 1;
PARTITION BY
字段有适当索引通过row_number() over()
函数解决重复键问题,不仅提高了代码的可读性,还能显著提升大批量数据处理的效率。掌握这一技术后,开发人员可以更优雅地处理各类数据合并场景。建议在实际应用中结合具体业务需求调整分区和排序策略,以达到最佳性能。
“`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。