2014-01-11 41 views
1

請幫助我知道基於rownum的刪除記錄,即使id是重複的,它也不會發生,但是如果是這種情況。在sql中使用rownum刪除重複記錄

select rownum,a.* from a; 

    ROWNUM   ID NAME 
---------- ---------- ---------- 
     1   1 leo_1 
     2   2 leo_2 
     3   3 leo_3 
     4   1 leo_1 
     5   2 leo_2 
     6   3 leo_3 

查詢嘗試,但刪除所有6行。

DELETE FROM a 
WHERE rownum not in 
(SELECT MIN(rownum) 
FROM a 
GROUP BY name); 

但這個查詢給出正確的結果:

SELECT MIN(rownum) 
FROM a 
GROUP BY name 

    ROWNUM 
---------- 
     1 
     2 
     3 

預期結果:

ROWNUM   ID NAME 
---------- ---------- ---------- 
     4   1 leo_1 
     5   2 leo_2 
     6   3 leo_3 
+0

預期結果是哪個查詢的結果? – tilda

+0

感謝您的所有答案。 – sunleo

回答

7

使用rowid

DELETE FROM table_name a 
WHERE EXISTS(SELECT 1 
       FROM table_name b 
       WHERE a.id = b.id 
        AND a.name = b.name 
        AND a.rowid > b.rowid) 

當然,你可以做a.rowid < b.rowidrowid只是該行的物理地址,因此刪除具有較大或較小地址的行是無關緊要的。

雖然您的預期結果沒有意義。

Expected Result : 

     ROWNUM   ID NAME 
    ---------- ---------- ---------- 
      4   1 leo_1 
      5   2 leo_2 
      6   3 leo_3 

結果集的rownum始終在查詢時間分配。這意味着特定的行可能會在不同的查詢中顯示不同的rownum值(或者多次運行同一查詢時)。 rownum始終是連續的,因此在同一個結果集中不能有rownum的結果集中有rownum的值,也沒有rownum的值1,2和3。無論重複的行刪除,你的結果將是

預期結果:

ROWNUM   ID NAME 
---------- ---------- ---------- 
     1   1 leo_1 
     2   2 leo_2 
     3   3 leo_3 

rownum值是任意的。這將是一種有效的Oracle返回

預期結果:

ROWNUM   ID NAME 
---------- ---------- ---------- 
     1   2 leo_2 
     2   3 leo_3 
     3   1 leo_1 
2
DELETE FROM a 
WHERE rowid not in 
(SELECT MIN(rowid) FROM a group BY name); 
+1

在查詢執行時分配給每行的行號.. Rownum是臨時的,但rowid是permanet – Sai

+0

,如果其他人在沒有RowId的情況下設計它? – Gary

0
delete from tb_test where c1 in (select c1 from (select c1,c2, 
row_number() over (partition by c2 order by c2) rn 
from tb_test) a where a.rn >1); 

C1是主鍵列,C2是重複值的列。