2016-06-22 12 views
2

Ich habe eine Tabelle mit mehreren Feldern. Die ersten 3 Felder sind die PK.Wie kann ich Duplikate loswerden, damit ich meine Tabelle PK ändern kann?

Field1 (PK) 
Field2 (PK) 
Field3 (PK) 
Field4 
Field5 
Field6 

Jetzt möchte ich die Tabellenstruktur ändern, um Field3 zu löschen und Field4 stattdessen Teil des PK zu machen. Das Problem ist, dass Field4 derzeit nicht eindeutig ist, so dass mehr als 1 Feld1 + Feld2 + Feld4 Kombination in der Tabelle sein kann. Ich möchte alle Extras löschen und nur eine Feld1 + Feld2 + Feld4 Kombination behalten.

Dies ist die Abfrage, die Sie mir, welche Kombinationen haben Duplikate Field1 + Feld2 + Field4 wissen lässt:

select Field1, Field2, Field4 
from myTable 
group by Field1, Field2, Field4 
having count(Field4)>1 

Aber ich kann nicht herausfinden, wie man diese nutzen, um die Duplikate zu löschen und lassen nur einen einzigen Datensatz (irgendwas wird es tun).

Antwort

1

Ich glaube, Sie so etwas tun:

delete m from 
myTable m join 
(
select Field1, Field2, Field4, max(field3) field3 
from myTable 
group by Field1, Field2, Field4 
having count(Field4)>1 
) m2 
on m.field1 = m2.field1 and m.field2 = m2.field2 and m.field4 = m2.field4 and m.field3 <> m2.field3 

Dieser Ansatz auf der Annahme basiert, dass (Field1, Field2, Field3) ein Primärschlüssel ist und damit jede doppelte Zeile (Field1, Field2, Field4) wird ein anderes Field3 haben.

+0

Das sieht groß! Vielen Dank! – froadie

+0

tatsächlich funktionierte es gut als eine Auswahl (ich habe die richtigen Datensätze, die gelöscht werden müssen), aber wenn ich es als ein Löschen versuche, bekomme ich einen Syntaxfehler .... 'Falsche Syntax nahe 'm'' und' Falsche Syntax nahe 'm2'' – froadie

+1

nur ein Syntaxproblem - sieht so aus, als müssten Sie "delete m from ..." – froadie

0

Eine Lösung, die ich denken kann, erfordern eine Identitätsspalte in Ihrer Tabelle hinzuzufügen:

alter table mytable 
add id int identity 

delete from mytabtle a where 
exists (select * from mytable b where a.field1=b.field1 and a.field2=b.field2 and a.field4=b.field4 and b.id>a.id) 
0

Mit einem CTE mit dem ROW_NUMBER() Fensterfunktion Sie etwas tun können:

;WITH CTE AS 
(
    SELECT Field1, 
      Field2, 
      ROW_NUMBER() OVER(PARTITION BY Field4 ORDER BY Field1, Field2) As RN 
    FROM MyTable 
) 

DELETE 
FROM CTE 
WHERE RN > 1