Oracle PL / SQL - 如何删除SQL表中的多个重复记录?

时间:2011-06-23 14:43:02

标签: sql oracle

我的表名TABLE1包含重复记录,如下所示:

ID  TYPE  AMOUNT NUMBER      DATE
--- ----  ------ ------ ---------
1    AAA   10.00 AAA123 22-JUN-11 
2    AAA    2.00 AAA123 22-JUN-11 
3    AAA   10.00 AAA123 22-JUN-11 
4    AAA    2.00 AAA123 22-JUN-11 
5    AAA   10.00 AAA123 22-JUN-11 
6    AAA    2.00 AAA123 22-JUN-11 
7    AAA   10.00 AAA123 22-JUN-11 
8    AAA    2.00 AAA123 22-JUN-11 
...  ...     ...    ...       ...
100  AAA   10.00 AAA123 22-JUN-11
101  AAA    2.00 AAA123 22-JUN-11

在这种情况下,我想删除所有重复的组合行,除了两个使用SQL或/通过PL / SQL,其中AMOUNT(10.00和2.00)。此外,包含不同数量的重复记录可能超过两个,如下所示:

ID  TYPE  AMOUNT NUMBER      DATE
--- ----  ------ ------ ---------
1    AAA   10.00 AAA123 22-JUN-11 
2    AAA    2.00 AAA123 22-JUN-11 
3    AAA   15.00 AAA123 22-JUN-11 
4    AAA   25.50 AAA123 22-JUN-11 
5    AAA   10.00 AAA123 22-JUN-11 
6    AAA    2.00 AAA123 22-JUN-11 
7    AAA   15.00 AAA123 22-JUN-11 
8    AAA   25.50 AAA123 22-JUN-11 
...

在上面的示例中,我只需要删除8条记录中的4条,其中AMOUNT应保留4条记录(10.00,2.00,15.00和25.50)。换句话说,我在一个表中有多组重复项(一个记录为2,另一个记录为4),多个行存在多个行。

4 个答案:

答案 0 :(得分:3)

试试这个:

DELETE 
    FROM  TABLE1
    WHERE ROWID IN 
    (
        SELECT ROW_ID_VAL
          FROM 
            (
                SELECT a.*, 
                       RANK() OVER(PARTITION BY AMOUNT ORDER BY ID DESC) RN, ROWID row_id_val
                  FROM TABLE1 a
            )
            WHERE rn <> 1
    )

答案 1 :(得分:2)

DATE列是唯一需要更多信息的列;否则使用:

DELETE FROM YOUR_TABLE
 WHERE EXISTS (SELECT NULL
                 FROM YOUR_TABLE t
                WHERE t.type = YOUR_TABLE.type
                  AND t.amount = YOUR_TABLE.amount
                  AND t.number = YOUR_TABLE.number
                  AND t.date = YOUR_TABLE.date
             GROUP BY t.type, t.amount, t.number, t.date
               HAVING MIN(t.id) != YOUR_TABLE.id)

YOUR_TABLE.列引用引用外部YOUR_TABLE,即要对其执行删除的表。这给了它一个相关的子查询效果,但是EXISTS并不能完全起作用。

答案 2 :(得分:1)

您可以遵循的一种方法如下:

每一行都有一个唯一的(row id)。您可以识别重复的行,然后根据(row id)删除重复的行。只需键入以下SELECT语句即可显示重复的行ID:

SELECT rowid from table_name;

答案 3 :(得分:0)

DECLARE

BEGIN

  for rec_ in (
                 SELECT type, amount, number, date , count(1) record_count
                    FROM table 1
                  GROUP BY type, amount, number, date
                 HAVING count(1) > 1) loop

      counter_ := 0;

      for rec2_ in ( select * from table1 where rec_.type = type
                                            and rec_.amount = amount
                                            and rec_.number = number
                                            and rec_.date = date) loop

            counter_ := counter_ + 1;            
            exit when counter_ = rec_.record_count;
            delete from table1 where id = rec2_.id;
       End loop;

  end loop;
END;