从表Oracle中删除重复记录

时间:2019-07-17 07:19:28

标签: sql oracle

我在下表中有重复的记录。


row no   name  eff_dt            address  pin
1             A       12-10-2007      AN         222
2             B       13-10-2007      AS         223
3             A        15-10-2007      AN        222
4             C        20-10-2007      AZ         222
5             C        27-10-2007      AZ         222
6             C        01-12-2007      AZ         222

我使用以下查询删除重复项:

delete from customer where rowid in(select rowid from(select rowid,name,eff_dt, address,pin, rownumber() over partition by name, address,pin order by eff_dt)rn from customer) where rn>1

该查询从上表中删除了行3、5和6。

但是根据我的需要,不应该删除rownum 3,因为当我将它与rownum 2比较时,它是不同的。但是由于它与rownum 1是重复的,因此它被查询删除了。

是否有通过这种方式进行重复记录清除的方法?喜欢只比较相邻的行吗?名称和eff_dt是表的主键。

4 个答案:

答案 0 :(得分:1)

假设您想保留最早的eff_dt记录,我们可以尝试使用EXISTS子句进行删除:

DELETE
FROM customer c1
WHERE EXISTS (SELECT 1 FROM customer c2
              WHERE c1.name = c2.name AND
                    c1.address = c2.address AND
                    c1.pin = c2.pin AND
                    c2.eff_dt < c1.eff_dt);

答案 1 :(得分:1)

您可以根据需要使用以下查询删除重复项:

DELETE FROM CUSTOMER C
WHERE
    ROW_NO IN (
        SELECT
            ROW_NO
        FROM
            (
                SELECT
                    ROW_NO,
                    --
                    NAME,
                    LAG(NAME, 1) OVER(
                        ORDER BY
                            ROW_NO
                    ) LAG_NAME,
                    --
                    ADDRESS,
                    LAG(ADDRESS, 1) OVER(
                        ORDER BY
                            ROW_NO
                    ) LAG_ADDRESS,
                    --
                    PIN,
                    LAG(PIN, 1) OVER(
                        ORDER BY
                            ROW_NO
                    ) LAG_PIN
                    --
                FROM
                    CUSTOMER
            )
        WHERE
            NAME = LAG_NAME
            AND ADDRESS = LAG_ADDRESS
            AND PIN = LAG_PIN
    )

db<>fiddle demo

干杯!

答案 2 :(得分:0)

delete  from customer where rowid in(
select rowid from (
select rowid,name,eff_dt, address,pin, NAME||'--'||ADDRESS|| '--'||PIN as curnt,
LAG(NAME||'--'||ADDRESS|| '--'||PIN , 1, 0) OVER (ORDER BY rowid asc) AS prev
from customer)
where curnt=prev);

信息: https://oracle-base.com/articles/misc/lag-lead-analytic-functions

答案 3 :(得分:0)

请尝试以下删除语句,也许正是您所需要的。

LAG(rowno,1,NULL)OVER(按名称,地址和eff_dt的引脚顺序划分)prev

DELETE FROM customer a
 WHERE EXISTS 
         (SELECT 1
            FROM (SELECT ROWNO, NAME, EFF_DT, PIN, address,
                         row_number() over (partition by name, address, pin order by eff_dt) rownm,
                         LAG(rowno, 1, NULL) OVER (partition by name, address, pin order by eff_dt) prev
                    FROM customer) b
           WHERE rownm > 1
             AND rowno - prev = 1
             AND b.rowno = a.rowno)