2012-04-04 10 views
3

Ich habe eine Tabellentransaktion, die Duplikate hat. Ich möchte den Datensatz behalten, der minimale ID hatte, und lösche alle Duplikate basierend auf vier Feldern DATE, AMOUNT, REFNUMBER, PARENTFOLDERID. Ich habe diese Abfrage geschrieben, aber ich bin mir nicht sicher, ob dies auf effiziente Weise geschrieben werden kann. Denkst du, dass es einen besseren Weg gibt? Ich frage, weil ich mir Sorgen um die Laufzeit mache.SQL zum Löschen der Duplikate in einer Tabelle

DELETE FROM TRANSACTION 
WHERE ID IN 
(SELECT FIT2.ID 
FROM 
(SELECT MIN(ID) AS ID, FIT.DATE, FIT.AMOUNT, FIT.REFNUMBER, FIT.PARENTFOLDERID 
FROM EWORK.TRANSACTION FIT 
GROUP BY FIT.DATE, FIT.AMOUNT , FIT.REFNUMBER, FIT.PARENTFOLDERID 
HAVING COUNT(1)>1 and FIT.AMOUNT >0) FIT1, 
EWORK.TRANSACTION FIT2 

WHERE FIT1.DATE=FIT2.DATE AND 
FIT1.AMOUNT=FIT2.AMOUNT AND 
FIT1.REFNUMBER=FIT2.REFNUMBER AND 
FIT1.PARENTFOLDERID=FIT2.PARENTFOLDERID AND 
FIT1.ID<>FIT2.ID) 

Antwort

3

Es wäre wahrscheinlich effizienter sein, etwas zu tun, wie

DELETE FROM transaction t1 
WHERE EXISTS(SELECT 1 
       FROM transaction t2 
       WHERE t1.date = t2.date 
        AND t1.refnumber = t2.refnumber 
        AND t1.parentFolderId = t2.parentFolderId 
        AND t2.id > t1.id) 
+0

versuchen Ja das funktioniert. Ich bin mir nicht sicher über die Leistung, aber es sieht besser lesbar aus. – mahen

+0

@justin: Ich denke, mit der analytischen Funktion ist viel mehr optimiert. Was Sie sagen? –

+0

@GauravSoni - Ich würde nicht erwarten, dass es in diesem Fall effizienter ist. Mit meinem oder Ihrem Ansatz muss Oracle zweimal die "transaction" -Tabelle treffen. Ich würde eher erwarten, dass ein Anti-Join etwas effizienter ist als der analytische Funktionsansatz. Aber es hängt von den verfügbaren Indizes, den Daten, der Anzahl der doppelten Zeilen usw. ab. Ich wäre nicht schockiert, wenn in einigen Fällen der analytische Funktionsansatz ein wenig effizienter wäre, aber ich würde erwarten, dass er einigermaßen nahe kommt . –

0

ich so etwas wie dies versuchen würde:

DELETE transaction 
FROM transaction 
LEFT OUTER JOIN 
    (
     SELECT MIN(id) as id, date, amount, refnumber, parentfolderid 
     FROM transaction 
     GROUP BY date, amount, refnumber, parentfolderid 
    ) as validRows 
ON transaction.id = validRows.id 
WHERE validRows.id IS NULL 
1
DELETE FROM transaction 
     WHERE ID IN (
       SELECT ID 
       FROM (SELECT ID, 
          ROW_NUMBER() OVER (PARTITION BY date 
                  ,amount 
                  ,refnumber 
                  ,parentfolderid 
               ORDER BY ID) rn 
               FROM transaction) 
       WHERE rn <> 1); 

Ich mag dieses

+0

@mahen: Wenn die Tabelle wirklich sehr groß ist, kann ich mit der unschätzbaren Leistung von Analytics optimieren –

+0

Ich glaube, dass Sie in Ihrer analytischen Funktion 'ORDER BY ID' wollen. –

+0

@JustinCave: Auf Vorschlag, habe ich meine erste Abfrage bearbeitet. Danke für Ihre Kommentare justin –

Verwandte Themen