Ich möchte hier mal einen kleinen Beitrag zum Thema „Duplikate aus einer Tabelle löschen“ schreiben.
Das ist ein weit verbreitetes Thema und es gibt dafür viele verschiedenen Möglichkeiten das zu tun.
Das einfachste ist wenn die Tabelle einen Primärschlüssel beinhaltet.
CREATE TABLE [dbo].[TableDuplicatesA] ([ID] [int] IDENTITY(1,1) NOT NULL, [Key] [varchar](50) NOT NULL CONSTRAINT [pk_dbo_TableDuplicatesA] PRIMARY KEY CLUSTERED ([ID] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY] INSERT INTO [dbo].[TableDuplicatesA] ([Key]) VALUES ('KeyA') INSERT INTO [dbo].[TableDuplicatesA] ([Key]) VALUES ('KeyB') INSERT INTO [dbo].[TableDuplicatesA] ([Key]) VALUES ('KeyB') INSERT INTO [dbo].[TableDuplicatesA] ([Key]) VALUES ('KeyC') INSERT INTO [dbo].[TableDuplicatesA] ([Key]) VALUES ('KeyD') INSERT INTO [dbo].[TableDuplicatesA] ([Key]) VALUES ('KeyD')
Der entsprechende DELETE ist einfach und übersichtlich:
DELETE FROM [dbo].[TableDuplicatesA] WHERE [ID] IN (SELECT max([ID]) FROM [dbo].[TableDuplicatesA] GROUP BY [Key] HAVING count([Key]) > 1)
Kniffliger wird es wenn es keinen Primärschlüssel gibt.
CREATE TABLE [dbo].[TableDuplicatesB] ([Key] [varchar](50) NOT NULL) ON [PRIMARY] INSERT INTO [dbo].[TableDuplicatesB] ([Key]) VALUES ('KeyA') INSERT INTO [dbo].[TableDuplicatesB] ([Key]) VALUES ('KeyB') INSERT INTO [dbo].[TableDuplicatesB] ([Key]) VALUES ('KeyB') INSERT INTO [dbo].[TableDuplicatesB] ([Key]) VALUES ('KeyC') INSERT INTO [dbo].[TableDuplicatesB] ([Key]) VALUES ('KeyD') INSERT INTO [dbo].[TableDuplicatesB] ([Key]) VALUES ('KeyD')
Hier ein paar Beispiele:
Die wohl schlechteste Variante ist diese hier:
SELECT DISTINCT [Key] INTO #temp FROM [dbo].[TableDuplicatesB] TRUNCATE TABLE [dbo].[TableDuplicatesB] INSERT INTO [dbo].[TableDuplicatesB] SELECT * FROM #temp SELECT * FROM [dbo].[TableDuplicatesA] DROP TABLE #temp
Besser und eleganter sind die nachfolgenden drei Beispiele:
DELETE t1 FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY [Key] ORDER BY [Key] DESC) [RowID] FROM [dbo].[TableDuplicatesB]) t1 WHERE [RowID] > 1
WITH CTE_Duplicates AS (SELECT ROW_NUMBER() OVER (PARTITION BY [Key] ORDER BY (SELECT 0)) [RowNumber] FROM [dbo].[TableDuplicatesB]) DELETE FROM CTE_Duplicates WHERE [RowNumber] > 1
DELETE t1 FROM (SELECT ROW_NUMBER() OVER (ORDER BY [Key]) AS [RowID], [Key] FROM [dbo].[TableDuplicatesB]) t1, (SELECT ROW_NUMBER() OVER (ORDER BY [Key]) AS [RowID], [Key] FROM [dbo].[TableDuplicatesB]) t2 WHERE t1.[Key] = t2.[Key] AND t1.[RowID] > t2.[RowID]
Anhand der Execution Plans könnt Ihr Euch selber ein Bild machen und entscheiden welche Query für Euch passt.
Hinterlasse einen Kommentar
Du musst angemeldet sein, um einen Kommentar schreiben zu können.