12 Stimmen

Kann ich Datenbankduplikate basierend auf mehreren Spalten löschen?

I stellte diese Frage vor einiger Zeit um doppelte Datensätze auf der Grundlage einer Spalte zu löschen. Die Antwort hat gut funktioniert:

delete from tbl
where id NOT in
(
select  min(id)
from tbl
group by sourceid
)

Ich habe jetzt eine ähnliche Situation, aber die Definition eines doppelten Datensatzes basiert auf mehreren Spalten. Wie kann ich das obige SQL ändern, um doppelte Datensätze zu identifizieren, wenn ein eindeutiger Datensatz als verkettet aus Col1 + Col2 + Col3 definiert ist. Könnte ich einfach etwas in der Art machen?

delete from tbl
where id NOT in
(
select  min(id)
from tbl
group by col1, col2, col3
)

26voto

Aaron Bertrand Punkte 259330

Hier werden die Zeilen angezeigt, die Sie behalten möchten:

;WITH x AS 
(
  SELECT col1, col2, col3, rn = ROW_NUMBER() OVER 
      (PARTITION BY col1, col2, col3 ORDER BY id)
  FROM dbo.tbl
)
SELECT col1, col2, col3 FROM x WHERE rn = 1;

Hier werden die Zeilen angezeigt, die Sie löschen möchten:

;WITH x AS 
(
  SELECT col1, col2, col3, rn = ROW_NUMBER() OVER 
      (PARTITION BY col1, col2, col3 ORDER BY id)
  FROM dbo.tbl
)
SELECT col1, col2, col3 FROM x WHERE rn > 1;

Wenn Sie sich vergewissert haben, dass die beiden oben genannten Sätze korrekt sind, können Sie sie mit den folgenden Schritten löschen:

;WITH x AS 
(
  SELECT col1, col2, col3, rn = ROW_NUMBER() OVER 
      (PARTITION BY col1, col2, col3 ORDER BY id)
  FROM dbo.tbl
)
DELETE x WHERE rn > 1;

Beachten Sie, dass in allen drei Abfragen die ersten 6 Zeilen identisch sind und nur die nachfolgende Abfrage nach dem CTE geändert wurde.

4voto

cadsjo Punkte 106

Versuchen Sie dies. Ich habe eine Tabelle erstellt tblA mit drei Spalten.

CREATE TABLE tblA
(
id int IDENTITY(1, 1),
colA int, 
colB int, 
colC int
)

Und einige doppelte Werte hinzugefügt.

INSERT INTO tblA VALUES (1, 2, 3)
INSERT INTO tblA VALUES (1, 2, 3)
INSERT INTO tblA VALUES (4, 5, 6)
INSERT INTO tblA VALUES (7, 8, 9)
INSERT INTO tblA VALUES (7, 8, 9)

Wenn Sie das Select durch ein Delete in der folgenden Anweisung ersetzen, funktioniert das Löschen mehrerer Spalten.

SELECT MIN(Id) as id
FROM
(
SELECT COUNT(*) as aantal, a.colA, a.colB, a.colC
FROM tblA       a
INNER JOIN tblA b   ON b.ColA = a.ColA
                    AND b.ColB = a.ColB
                    AND b.ColC = a.ColC
GROUP BY a.id, a.colA, a.colB, a.colC
HAVING COUNT(*) > 1
) c
INNER JOIN tblA d ON d.ColA = c.ColA
                    AND d.ColB = c.ColB
                    AND d.ColC = c.ColC
GROUP BY d.colA, d.colB, d.colC

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X