2011-06-23 45 views
3

我有表名TABLE1包含重複的記錄,如下所示:Oracle PL/SQL - 如何刪除SQL表中的多個重複記錄?

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)。另外,含有不同量的重複recordes可以多於兩個,如下面所示是:

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 
... 

在上述例子中,我只需要4出8條記錄,其中量應保持4條記錄(10.00到刪除,2.00,15.00和25.50)。換句話說,我在一個表中有多組重複項(一個爲2個記錄,另一個爲4個等) - 存在多個存在的多個行。

+0

那麼列有助於重複?只有金額? – Chandu

+0

當答案確實只使用SQL時,社區對標記PLSQL時會不滿。對於什麼版本的Oracle? –

回答

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不完全是這樣。

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 
    ) 
+0

在這種情況下'ROW_NUMBER'可能是更好的選擇? –

+0

@OMG Pointes:我認爲Id字段是唯一的,並且RANK仍然正常,因爲我使用ID在窗口中排序數據。 – Chandu

+0

確實 - 不介意我,咖啡之前(tm) –

1

一種方法就可以按照舉例如下:

每一行都有一個唯一的(row id)。您可以識別當然重複的行,然後根據(row id)刪除重複的行。只需鍵入以下SELECT聲明透露重複的行ID:

SELECT rowid from table_name;

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;