Oracle 去重复问题

1. 数据样例

1.1 创建表

create table SAMPLE_TEST
(
product_id   NUMBER,
product_name VARCHAR2(100),
product_price NUMBER(10,2),
product_desc VARCHAR2(2000)
);

comment on table SAMPLE_TEST
 is '产品信息表';
comment on column SAMPLE_TEST.product_id
 is '产品代码';
comment on column SAMPLE_TEST.product_name
 is '产品名称';
comment on column SAMPLE_TEST.product_price
 is '产品价格';
comment on column SAMPLE_TEST.product_desc
 is '产品介绍';

1.2 写入数据

insert into sample_test (PRODUCT_ID, PRODUCT_NAME, PRODUCT_PRICE, PRODUCT_DESC)
values (1, 'iPhone 11 Pro Max', 9800.00, '手机');
commit;
insert into sample_test (PRODUCT_ID, PRODUCT_NAME, PRODUCT_PRICE, PRODUCT_DESC)
values (1, 'iPhone 11 Pro Max', 9800.00, '手机');
commit;
insert into sample_test (PRODUCT_ID, PRODUCT_NAME, PRODUCT_PRICE, PRODUCT_DESC)
values (2, 'iPhone 12 Pro Max', 10888.00, '手机');
commit;
insert into sample_test (PRODUCT_ID, PRODUCT_NAME, PRODUCT_PRICE, PRODUCT_DESC)
values (2, 'iPhone 12 Pro Max', 10888.00, '手机');
commit;
insert into sample_test (PRODUCT_ID, PRODUCT_NAME, PRODUCT_PRICE, PRODUCT_DESC)
values (3, 'iPhone 13 Pro Max', 11888.00, '手机');
commit;
insert into sample_test (PRODUCT_ID, PRODUCT_NAME, PRODUCT_PRICE, PRODUCT_DESC)
values (3, 'iPhone 13 Pro Max', 11888.00, '手机');
commit;
insert into sample_test (PRODUCT_ID, PRODUCT_NAME, PRODUCT_PRICE, PRODUCT_DESC)
values (3, 'iPhone 13 Pro Max', 11888.00, '手机');
commit;
insert into sample_test (PRODUCT_ID, PRODUCT_NAME, PRODUCT_PRICE, PRODUCT_DESC)
values (4, 'iPhone 14 Pro Max', 12888.00, '手机');
commit;
insert into sample_test (PRODUCT_ID, PRODUCT_NAME, PRODUCT_PRICE, PRODUCT_DESC)
values (4, 'iPhone 14 Pro Max', 12888.00, '手机');
commit;
insert into sample_test (PRODUCT_ID, PRODUCT_NAME, PRODUCT_PRICE, PRODUCT_DESC)
values (4, 'iPhone 14 Pro Max', 12888.00, '手机');
commit;

2. 查询数据

2.1 原始数据

Oracle 去重复问题

3 . 问题情景

问题: 现需要去除重复数据,要求所有数据无论重复多少次, 只保留一条.

3.1 方法一

具体实现流程如下:

3.1.1 排序


SELECT ROW_NUMBER() OVER(PARTITION BY t.product_id, t.product_name, t.product_price ORDER BY t.rowid) rn,
      t.*
 FROM sample_test t;

3.1.2 结果

Oracle 去重复问题

3.1.3 查询删除对象

建议在删除数据前, 先查询一下, 确认查询结果, 判断where条件是否正确, 防止出现事故


SELECT *
 FROM sample_test t1
WHERE EXISTS (SELECT 1
         FROM (SELECT ROW_NUMBER() OVER(PARTITION BY t.product_id, t.product_name, t.product_price ORDER BY t.rowid)rn,
                      t.*
                 FROM sample_test t) t2
        WHERE t2.rn > 1
          AND t1.rowid = t2.rowid);
Oracle 去重复问题

3.1.4 删除目标数据

确认查询结果是需要删除的数据范围, 复制查询条件到Delete语句

注意‼ : 如果是生产库要记得备份数据, 同时在处理删除之前, 要想好恢复数据的方法

DELETE FROM sample_test t1
WHERE EXISTS (SELECT 1
         FROM (SELECT ROW_NUMBER() OVER(PARTITION BY t.product_id, t.product_name, t.product_price ORDER BY t.rowid)rn,
                      t.*
                 FROM sample_test t) t2
        WHERE t2.rn > 1
          AND t1.rowid = t2.rowid);
Oracle 去重复问题

3.2 方法二

3.2.1 取最小rowid

SELECT MIN(t.rowid) min_rowid FROM sample_test t GROUP BY t.product_id;
Oracle 去重复问题

3.2.2 判断取反删除

保留此rowid对应的数据, 不在此范围内的数据删除, 先查询一下是否正确


SELECT *
 FROM sample_test t1
WHERE NOT EXISTS
(SELECT 1
         FROM (SELECT MIN(t.rowid) min_rowid FROM sample_test t GROUP BY t.product_id) t2
        WHERE t1.rowid = t2.min_rowid);
Oracle 去重复问题

3.2.3 执行删除

确认查询结果是需要删除的数据范围, 复制查询条件到Delete语句

注意‼ : 如果是生产库要记得备份数据, 同时在处理删除之前, 要想好恢复数据的方法


DELETE
 FROM sample_test t1
WHERE NOT EXISTS
(SELECT 1
         FROM (SELECT MIN(t.rowid) min_rowid FROM sample_test t GROUP BY t.product_id) t2
        WHERE t1.rowid = t2.min_rowid);

3.2.4 最终结果

当然还有其他方法, 以上是我平时工作中比较常用的且的方法. 比较喜欢用第一种, 因为有的时候, 实际上是在生产库中处理数据, 需求比较复杂.

Oracle 去重复问题

展开阅读全文

更新时间:2024-09-05

标签:行号   范围内   语句   备份   最小   对象   条件   方法   数据   手机

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top