Как я могу удалить дубликаты строк?

Каков наилучший способ удалить повторяющиеся строки из довольно большой SQL Serverтаблицы (т.е. 300 000+ строк)?

Строки, конечно, не будут идеальными дубликатами из-за существования поля RowIDидентичности.

MyTable

RowID int not null identity(1,1) primary key,
Col1 varchar(20) not null,
Col2 varchar(2048) not null,
Col3 tinyint not null
20.08.2008 21:51:29
Быстрый совет для пользователей PostgreSQL, читающих это (много, исходя из того, как часто он связан): Pg не представляет термины CTE как обновляемые представления, поэтому вы не можете DELETE FROMнапрямую использовать термин CTE. См. Stackoverflow.com/q/18439054/398670
Craig Ringer 26.08.2013 07:59:12
@CraigRinger то же самое верно и для Sybase - я собрал остальные решения здесь (должно быть также для PG и других: stackoverflow.com/q/19544489/1855801 (просто замените ROWID()функцию на столбец RowID, если есть)
maf-soft 29.10.2013 06:41:33
Просто чтобы добавить оговорку здесь. При запуске любого процесса дедупликации, всегда дважды проверяйте, что вы удаляете первым! Это одна из тех областей, где очень часто случайно удаляются хорошие данные.
Jeff Davis 4.12.2013 01:45:38
30 ОТВЕТОВ
РЕШЕНИЕ

Предполагая , что не аннулирует, то GROUP BYуникальные колонны, и RowId как ряд , чтобы сохранить. Затем просто удалите все, что не имеет идентификатора строки:SELECTMIN (or MAX)

DELETE FROM MyTable
LEFT OUTER JOIN (
   SELECT MIN(RowId) as RowId, Col1, Col2, Col3 
   FROM MyTable 
   GROUP BY Col1, Col2, Col3
) as KeepRows ON
   MyTable.RowId = KeepRows.RowId
WHERE
   KeepRows.RowId IS NULL

Если у вас есть GUID вместо целого числа, вы можете заменить

MIN(RowId)

с

CONVERT(uniqueidentifier, MIN(CONVERT(char(36), MyGuidColumn)))
1139
12.06.2017 11:06:07
Будет ли это работать также? DELETE FROM MyTable WHERE RowId NOT IN (SELECT MIN(RowId) FROM MyTable GROUP BY Col1, Col2, Col3);
Georg Schölly 23.09.2010 11:13:47
@Andriy - В SQL Server LEFT JOINявляется менее эффективным , чем NOT EXISTS sqlinthewild.co.za/index.php/2010/03/23/... Тот же сайт также сравнивает NOT INпротив NOT EXISTS. sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in Из трех я считаю, что NOT EXISTSработает лучше всего. Все три создадут план с самостоятельным объединением, хотя этого можно избежать.
Martin Smith 14.01.2011 09:17:50
@Martin, @Georg: Итак, я сделал небольшой тест. Большая таблица была создана и заполнена, как описано здесь: sqlinthewild.co.za/index.php/2010/03/23/… Затем были созданы два SELECT, один с использованием метода LEFT JOIN + WHERE IS NULL, другой с использованием NOT В одном. Затем я приступил к выполнению планов, и угадайте, что? Стоимость запроса составила 18% для LEFT JOIN против 82% для NOT IN, что меня сильно удивило. Я мог бы сделать то, чего не должен был делать, или наоборот, что, если это правда, мне бы очень хотелось знать.
Andriy M 14.01.2011 10:23:10
@ GeorgSchölly предоставил элегантный ответ. Я использовал его в таблице, где моя ошибка PHP создала дублирующиеся строки.
Philip Kearns 28.05.2013 17:02:13
Извините, но почему DELETE MyTable FROM MyTableправильный синтаксис? Я не вижу размещения имени таблицы сразу после DELETEопции в документации здесь . Извините, если это очевидно для других; Я новичок в SQL, просто пытаюсь учиться. Что важнее, чем почему это работает: в чем разница между включением имени таблицы или нет?
levininja 6.11.2013 20:28:03

На сайте поддержки Microsoft есть хорошая статья об удалении дубликатов . Это довольно консервативно - они заставляют вас делать все в отдельных шагах - но это должно хорошо работать с большими столами.

Я использовал для этого самостоятельные объединения в прошлом, хотя, вероятно, это можно было бы с помощью предложения HAVING:

DELETE dupes
FROM MyTable dupes, MyTable fullTable
WHERE dupes.dupField = fullTable.dupField 
AND dupes.secondDupField = fullTable.secondDupField 
AND dupes.uniqueField > fullTable.uniqueField
149
19.06.2017 23:36:49
идеальный! я обнаружил, что это самый эффективный способ удаления дублирующихся строк в моей старой версии mariadb 10.1.xx. Спасибо!
Drunken M 11.02.2020 22:47:16
Намного проще и понятнее!
Marc 21.02.2020 19:12:44

Вот еще одна хорошая статья по удалению дубликатов .

Здесь обсуждается, почему это сложно: « SQL основан на реляционной алгебре, и дубликаты не могут возникать в реляционной алгебре, потому что дубликаты не допускаются в наборе ».

Решение временной таблицы и два примера mysql.

В будущем вы собираетесь предотвратить это на уровне базы данных или с точки зрения приложения. Я бы предложил уровень базы данных, потому что ваша база данных должна отвечать за поддержание ссылочной целостности, разработчики просто вызовут проблемы;)

12
20.08.2008 21:58:00
SQL основан на множестве множеств. Но даже если он основан на множествах, эти два кортежа (1, a) и (2, a) различны.
Andrew 17.10.2011 23:50:53

Да, конечно. Используйте временную таблицу. Если вам нужен один, не очень производительный оператор, который «работает», вы можете использовать:

DELETE FROM MyTable WHERE NOT RowID IN
    (SELECT 
        (SELECT TOP 1 RowID FROM MyTable mt2 
        WHERE mt2.Col1 = mt.Col1 
        AND mt2.Col2 = mt.Col2 
        AND mt2.Col3 = mt.Col3) 
    FROM MyTable mt)

По сути, для каждой строки в таблице подвыбор находит верхний RowID всех строк, которые в точности соответствуют рассматриваемой строке. Таким образом, вы получите список RowID, которые представляют «оригинальные» недублированные строки.

12
10.06.2013 19:28:05

С уровня приложения (к сожалению). Я согласен, что правильный способ предотвращения дублирования на уровне базы данных - использование уникального индекса, но в SQL Server 2005 индекс может быть только 900 байтов, и мое поле varchar (2048) срывает это.

Я не знаю, насколько хорошо это будет работать, но я думаю, что вы могли бы написать триггер для обеспечения этого, даже если вы не можете сделать это напрямую с индексом. Что-то типа:

-- given a table stories(story_id int not null primary key, story varchar(max) not null)
CREATE TRIGGER prevent_plagiarism 
ON stories 
after INSERT, UPDATE 
AS 
    DECLARE @cnt AS INT 

    SELECT @cnt = Count(*) 
    FROM   stories 
           INNER JOIN inserted 
                   ON ( stories.story = inserted.story 
                        AND stories.story_id != inserted.story_id ) 

    IF @cnt > 0 
      BEGIN 
          RAISERROR('plagiarism detected',16,1) 

          ROLLBACK TRANSACTION 
      END 

Кроме того, varchar (2048) звучит для меня подозрительно (некоторые вещи в жизни имеют размер 2048 байт, но это довольно редко); разве это не должно быть varchar (max)?

7
28.07.2014 13:06:13
  1. Создать новую пустую таблицу с той же структурой

  2. Выполнить запрос, как это

    INSERT INTO tc_category1
    SELECT *
    FROM tc_category
    GROUP BY category_id, application_id
    HAVING count(*) > 1
  3. Затем выполните этот запрос

    INSERT INTO tc_category1
    SELECT *
    FROM tc_category
    GROUP BY category_id, application_id
    HAVING count(*) = 1
9
23.07.2015 12:43:48

У меня была таблица, где мне нужно было сохранить неповторяющиеся строки. Я не уверен в скорости или эффективности.

DELETE FROM myTable WHERE RowID IN (
  SELECT MIN(RowID) AS IDNo FROM myTable
  GROUP BY Col1, Col2, Col3
  HAVING COUNT(*) = 2 )
11
11.12.2009 13:47:21
Это предполагает, что существует не более 1 дубликата.
Martin Smith 2.10.2010 20:11:07
Почему нет HAVING COUNT(*) > 1?
Philipp M 7.10.2014 09:26:36

Другой возможный способ сделать это

; 

--Ensure that any immediately preceding statement is terminated with a semicolon above
WITH cte
     AS (SELECT ROW_NUMBER() OVER (PARTITION BY Col1, Col2, Col3 
                                       ORDER BY ( SELECT 0)) RN
         FROM   #MyTable)
DELETE FROM cte
WHERE  RN > 1;

Я использую ORDER BY (SELECT 0)выше, поскольку это произвольно, какой ряд сохранить в случае ничьей.

Чтобы сохранить последнюю RowIDверсию, например, вы можете использоватьORDER BY RowID DESC

Планы выполнения

План выполнения для этого часто проще и эффективнее, чем в принятом ответе, так как не требует самостоятельного соединения.

Планы выполнения

Однако это не всегда так. Единственное место, где GROUP BYрешение может быть предпочтительным, - это ситуации, когда хеш-агрегат будет выбран предпочтительнее, чем агрегат потока.

ROW_NUMBERРешение всегда будет давать в значительной степени тот же план , тогда как GROUP BYстратегия является более гибкой.

Планы выполнения

Факторы, которые могли бы способствовать подходу агрегирования хэшей

  • Нет полезного индекса для столбцов разделения
  • относительно меньше групп с относительно большим количеством дубликатов в каждой группе

В крайних версиях этого второго случая (если существует очень мало групп с множеством дубликатов в каждой), можно также рассмотреть возможность просто вставить строки, чтобы сохранить их в новую таблицу, затем TRUNCATE-в оригинале и скопировать их обратно, чтобы минимизировать ведение журнала по сравнению с удалением очень высокая пропорция рядов.

757
21.02.2020 19:19:26
Если я могу добавить: принятый ответ не работает с таблицами, которые используют uniqueidentifier. Этот намного проще и отлично работает на любом столе. Спасибо Мартин.
BrunoLM 16.11.2010 15:50:44
Это такой потрясающий ответ! Это сработало, когда я удалил старый ПК, прежде чем понял, где дубликаты. +100
Mikael Eliasson 19.07.2011 19:55:29
Я предлагаю спросить и затем ответить на этот вопрос (с этим ответом) на DBA.SE. Затем мы можем добавить его в наш список канонических ответов .
Nick Chammas 5.06.2012 23:49:04
В отличие от принятого ответа, это также работало с таблицей, в которой не было ключа ( RowId) для сравнения.
vossad01 4.03.2013 17:39:32
Этот не работает на всех версиях SQL-сервера, с другой стороны
David 24.03.2015 15:31:48
delete t1
from table t1, table t2
where t1.columnA = t2.columnA
and t1.rowid>t2.rowid

Postgres:

delete
from table t1
using table t2
where t1.columnA = t2.columnA
and t1.rowid > t2.rowid
61
7.11.2015 00:48:15
Зачем размещать решение Postgres по вопросу SQL Server?
Lankymart 8.03.2016 14:34:07
@Lankymart Потому что сюда приходят и пользователи postgres. Посмотрите на оценку этого ответа.
Gabriel 15.01.2018 15:38:19
Я видел это в некоторых популярных вопросах SQL, как здесь , здесь и здесь . ОП получил свой ответ, и все остальные тоже получили некоторую помощь. Без проблем ИМХО.
Gabriel 15.01.2018 19:39:13

Следующий запрос полезен для удаления повторяющихся строк. Таблицы в этом примере , имеют в IDкачестве столбца идентификации , а столбцы , которые имеют дублирующие данные являются Column1, Column2и Column3.

DELETE FROM TableName
WHERE  ID NOT IN (SELECT MAX(ID)
                  FROM   TableName
                  GROUP  BY Column1,
                            Column2,
                            Column3
                  /*Even if ID is not null-able SQL Server treats MAX(ID) as potentially
                    nullable. Because of semantics of NOT IN (NULL) including the clause
                    below can simplify the plan*/
                  HAVING MAX(ID) IS NOT NULL) 

Следующий скрипт показывает использование GROUP BY, HAVING, ORDER BYв одном запросе, и возвращает результаты с повторяющимся столбца и его подсчета.

SELECT YourColumnName,
       COUNT(*) TotalCount
FROM   YourTableName
GROUP  BY YourColumnName
HAVING COUNT(*) > 1
ORDER  BY COUNT(*) DESC 
97
4.01.2013 16:41:25
Ошибка MySQL с первым скриптом «Вы не можете указать целевую таблицу TableName для обновления в предложении FROM»
D.Rosado 13.06.2012 10:54:29
Помимо ошибки D.Rosado, о которой уже сообщалось, ваш первый запрос также очень медленный. Соответствующий запрос SELECT занял в моей настройке + - в 20 раз больше, чем принятый ответ.
parvus 3.01.2013 08:24:54
@parvus - вопрос помечен SQL Server, а не MySQL. Синтаксис хорошо в SQL Server. Также MySQL, как известно, плохо оптимизирует подзапросы, см., Например, здесь . Этот ответ хорошо в SQL Server. На самом деле NOT INчасто работает лучше, чем OUTER JOIN ... NULL. Я бы добавил HAVING MAX(ID) IS NOT NULLк запросу, хотя семантически это не нужно, поскольку это может улучшить пример
Martin Smith 4.01.2013 16:27:14
Прекрасно работает в PostgreSQL 8.4.
nortally 5.05.2014 23:48:21

Используя приведенный ниже запрос, мы можем удалить дубликаты записей на основе одного или нескольких столбцов. ниже запрос удаляется на основе двух столбцов. Имя таблицы: testingи имена столбцовempno,empname

DELETE FROM testing WHERE empno not IN (SELECT empno FROM (SELECT empno, ROW_NUMBER() OVER (PARTITION BY empno ORDER BY empno) 
AS [ItemNumber] FROM testing) a WHERE ItemNumber > 1)
or empname not in
(select empname from (select empname,row_number() over(PARTITION BY empno ORDER BY empno) 
AS [ItemNumber] FROM testing) a WHERE ItemNumber > 1)
9
9.03.2012 15:50:38
CREATE TABLE car(Id int identity(1,1), PersonId int, CarId int)

INSERT INTO car(PersonId,CarId)
VALUES(1,2),(1,3),(1,2),(2,4)

--SELECT * FROM car

;WITH CTE as(
SELECT ROW_NUMBER() over (PARTITION BY personid,carid order by personid,carid) as rn,Id,PersonID,CarId from car)

DELETE FROM car where Id in(SELECT Id FROM CTE WHERE rn>1)
6
11.07.2012 11:46:52
SELECT  DISTINCT *
      INTO tempdb.dbo.tmpTable
FROM myTable

TRUNCATE TABLE myTable
INSERT INTO myTable SELECT * FROM tempdb.dbo.tmpTable
DROP TABLE tempdb.dbo.tmpTable
16
10.10.2012 11:21:53
Усечение не будет работать, если у вас есть ссылки на внешние ключи на myTable.
Sameer 27.06.2013 14:58:12

Я хотел бы упомянуть этот подход, а также то, что он может быть полезен и работает на всех серверах SQL: довольно часто есть только один - два дубликата, и идентификаторы и количество дубликатов известны. В таком случае:

SET ROWCOUNT 1 -- or set to number of rows to be deleted
delete from myTable where RowId = DuplicatedID
SET ROWCOUNT 0
7
30.01.2013 19:45:37

Быстро и грязно удалить точно дублированные строки (для небольших таблиц):

select  distinct * into t2 from t1;
delete from t1;
insert into t1 select *  from t2;
drop table t2;
22
5.02.2013 21:44:52
Обратите внимание, что вопрос на самом деле указывает на неточное дублирование (из-за идентификатора строки).
Dennis Jaheruddin 16.07.2015 12:00:39

Еще одно простое решение можно найти по ссылке, вставленной здесь . Это легко понять и кажется эффективным для большинства подобных проблем. Это для SQL Server, но используемая концепция более чем приемлема.

Вот соответствующие части со связанной страницы:

Рассмотрим эти данные:

EMPLOYEE_ID ATTENDANCE_DATE
A001    2011-01-01
A001    2011-01-01
A002    2011-01-01
A002    2011-01-01
A002    2011-01-01
A003    2011-01-01

Итак, как мы можем удалить эти дубликаты данных?

Сначала вставьте столбец идентификаторов в эту таблицу, используя следующий код:

ALTER TABLE dbo.ATTENDANCE ADD AUTOID INT IDENTITY(1,1)  

Используйте следующий код, чтобы решить это:

DELETE FROM dbo.ATTENDANCE WHERE AUTOID NOT IN (SELECT MIN(AUTOID) _
    FROM dbo.ATTENDANCE GROUP BY EMPLOYEE_ID,ATTENDANCE_DATE) 
13
5.11.2013 21:39:20
«Легко понять», «кажется , чтобы быть эффективным», но ни слова о том, что метод заключается в том . Просто представьте себе , что связь становится недействительным, какая польза была бы тогда знать , что этот метод был легко понять и эффективно? Пожалуйста, рассмотрите возможность добавления основных частей описания метода в ваш пост, иначе это не ответ.
Andriy M 7.08.2013 12:42:07
Этот метод полезен для таблиц, в которых еще не определена идентичность. Часто вам нужно избавиться от дубликатов, чтобы определить первичный ключ!
Jeff Davis 5.11.2013 21:25:39
@JeffDavis - ROW_NUMBERВерсия отлично подходит для этого случая, не нужно вдаваться в подробности добавления нового столбца перед началом.
Martin Smith 2.03.2014 11:51:27

Это удалит повторяющиеся строки, кроме первой строки

DELETE
FROM
    Mytable
WHERE
    RowID NOT IN (
        SELECT
            MIN(RowID)
        FROM
            Mytable
        GROUP BY
            Col1,
            Col2,
            Col3
    )

См. ( Http://www.codeproject.com/Articles/157977/Remove-Duplicate-Rows-from-a-Table-in-SQL-Server )

39
17.03.2017 10:20:15
Для mysql это выдаст ошибку: Код ошибки: 1093. Вы не можете указать целевую таблицу «Mytable» для обновления в предложении FROM. но это небольшое изменение будет работать для mysql: УДАЛИТЬ ИЗ Mytable, ГДЕ НЕ ВХОДИТ ROWID (ВЫБЕРИТЕ ID ИЗ (ВЫБЕРИТЕ МИН (RowID) КАК ИД ИЗ ГРУППЫ Mytable ПО Col1, Col2, Col3) AS TEMP)
Ritesh 29.02.2016 18:33:30

Другой способ - создать новую таблицу с теми же полями и уникальным индексом . Затем переместите все данные из старой таблицы в новую таблицу . Автоматически SQL SERVER игнорирует (есть также вариант, что делать, если будет повторяющееся значение: игнорировать, прерывать или sth) повторяющихся значений. Итак, у нас одна и та же таблица без повторяющихся строк. Если вы не хотите уникальный индекс, после передачи данных вы можете удалить его .

Специально для больших таблиц вы можете использовать DTS (пакет SSIS для импорта / экспорта данных), чтобы быстро перенести все данные в вашу новую уникально проиндексированную таблицу. Для 7 миллионов подряд это займет всего несколько минут.

10
27.01.2014 15:57:32
DELETE
FROM
    table_name T1
WHERE
    rowid > (
        SELECT
            min(rowid)
        FROM
            table_name T2
        WHERE
            T1.column_name = T2.column_name
    );
7
17.03.2017 09:20:30
Привет, Тина, ты пропустил имя Алисы таблицы T1 после комментария удаления, иначе произойдет исключение синтаксиса.
Nagaraj M 1.08.2017 11:21:34
DELETE 
FROM MyTable
WHERE NOT EXISTS (
              SELECT min(RowID)
              FROM Mytable
              WHERE (SELECT RowID 
                     FROM Mytable
                     GROUP BY Col1, Col2, Col3
                     ))
               );
6
23.07.2015 12:42:54

Я думал, что поделюсь своим решением, так как оно работает при особых обстоятельствах. В моем случае таблица с дублирующимися значениями не имела внешнего ключа (потому что значения были продублированы из другой базы данных).

begin transaction
-- create temp table with identical structure as source table
Select * Into #temp From tableName Where 1 = 2

-- insert distinct values into temp
insert into #temp 
select distinct * 
from  tableName

-- delete from source
delete from tableName 

-- insert into source from temp
insert into tableName 
select * 
from #temp

rollback transaction
-- if this works, change rollback to commit and execute again to keep you changes!!

PS: при работе над такими вещами я всегда использую транзакцию, это не только гарантирует, что все выполняется целиком, но и позволяет мне тестировать, не рискуя ничем. Но, конечно, вы должны сделать резервную копию в любом случае, просто чтобы быть уверенным ...

14
27.01.2014 12:20:09

Я предпочитаю решение подзапроса \ имеющее count (*)> 1 для внутреннего объединения, потому что мне было легче читать, и было очень легко превратиться в оператор SELECT, чтобы проверить, что будет удалено, прежде чем вы его запустите.

--DELETE FROM table1 
--WHERE id IN ( 
     SELECT MIN(id) FROM table1 
     GROUP BY col1, col2, col3 
     -- could add a WHERE clause here to further filter
     HAVING count(*) > 1
--)
20
1.03.2014 07:40:18
Разве это не удаляет все записи, которые отображаются во внутреннем запросе. Нам нужно удалить только дубликаты и сохранить оригинал.
Sandy 15.05.2015 20:05:21
Вы возвращаете только тот с самым низким идентификатором, основанный на минимальном (id) в предложении select.
James Errico 18.05.2015 00:24:51
Раскомментируйте первую, вторую и последнюю строки запроса.
James Errico 18.05.2015 16:25:25
Это не очистит все дубликаты. Если у вас есть 3 строки, которые являются дубликатами, он выберет только строку с MIN (id) и удалит ее, оставив две строки, которые являются дубликатами.
Chloe 6.11.2015 23:48:21
Тем не менее, я закончил тем, что использовал это утверждение, повторяемое снова и снова, так что оно действительно будет прогрессировать вместо того, чтобы отключить тайм-аут соединения или перевести компьютер в спящий режим. Я изменил его, чтобы MAX(id)устранить последние дубликаты, и добавил LIMIT 1000000к внутреннему запросу, чтобы не пришлось сканировать всю таблицу. Это показало прогресс намного быстрее, чем другие ответы, которые, казалось бы, зависали часами. После того, как таблица была сокращена до управляемого размера, вы можете закончить с другими запросами. Совет: убедитесь, что col1 / col2 / col3 имеют индексы для группировки по.
Chloe 7.11.2015 19:44:25
DELETE LU 
FROM   (SELECT *, 
               Row_number() 
                 OVER ( 
                   partition BY col1, col1, col3 
                   ORDER BY rowid DESC) [Row] 
        FROM   mytable) LU 
WHERE  [row] > 1 
43
15.10.2014 11:08:49
Я получаю это сообщение в Azure SQL DW: предложение FROM в настоящее время не поддерживается в инструкции DELETE.
Amit 22.10.2016 06:54:20

Используя CTE. Идея состоит в том, чтобы объединить один или несколько столбцов, которые образуют дублирующуюся запись, а затем удалить то, что вам нравится:

;with cte as (
    select 
        min(PrimaryKey) as PrimaryKey
        UniqueColumn1,
        UniqueColumn2
    from dbo.DuplicatesTable 
    group by
        UniqueColumn1, UniqueColumn1
    having count(*) > 1
)
delete d
from dbo.DuplicatesTable d 
inner join cte on 
    d.PrimaryKey > cte.PrimaryKey and
    d.UniqueColumn1 = cte.UniqueColumn1 and 
    d.UniqueColumn2 = cte.UniqueColumn2;
14
12.02.2018 15:12:24
Я думаю, что вы пропустили AND в вашем JOIN.
Justin R. 16.03.2016 20:32:50

Этот запрос показал очень хорошую производительность для меня:

DELETE tbl
FROM
    MyTable tbl
WHERE
    EXISTS (
        SELECT
            *
        FROM
            MyTable tbl2
        WHERE
            tbl2.SameValue = tbl.SameValue
        AND tbl.IdUniqueValue < tbl2.IdUniqueValue
    )

он удалил 1M строк за чуть более 30 секунд из таблицы 2M (50% дубликатов)

14
17.03.2017 07:25:57

Если вы хотите предварительно просмотреть строки, которые вы собираетесь удалить, и сохранить контроль над тем, какие из дубликатов строки оставить. Смотрите http://developer.azurewebsites.net/2014/09/better-sql-group-by-find-duplicate-data/

with MYCTE as (
  SELECT ROW_NUMBER() OVER (
    PARTITION BY DuplicateKey1
                ,DuplicateKey2 -- optional
    ORDER BY CreatedAt -- the first row among duplicates will be kept, other rows will be removed
  ) RN
  FROM MyTable
)
DELETE FROM MYCTE
WHERE RN > 1
6
1.01.2015 15:32:03

Я бы предпочел CTE для удаления дублирующихся строк из таблицы сервера SQL

Настоятельно рекомендуем следовать этой статье :: http://codaffection.com/sql-server-article/delete-duplicate-rows-in-sql-server/

сохраняя оригинал

WITH CTE AS
(
SELECT *,ROW_NUMBER() OVER (PARTITION BY col1,col2,col3 ORDER BY col1,col2,col3) AS RN
FROM MyTable
)

DELETE FROM CTE WHERE RN<>1

не сохраняя оригинал

WITH CTE AS
(SELECT *,R=RANK() OVER (ORDER BY col1,col2,col3)
FROM MyTable)
 
DELETE CTE
WHERE R IN (SELECT R FROM CTE GROUP BY R HAVING COUNT(*)>1)
32
12.08.2018 03:31:33

Использовать это

WITH tblTemp as
(
SELECT ROW_NUMBER() Over(PARTITION BY Name,Department ORDER BY Name)
   As RowNumber,* FROM <table_name>
)
DELETE FROM tblTemp where RowNumber >1
11
23.07.2015 11:42:20
alter table MyTable add sno int identity(1,1)
    delete from MyTable where sno in
    (
    select sno from (
    select *,
    RANK() OVER ( PARTITION BY RowID,Col3 ORDER BY sno DESC )rank
    From MyTable
    )T
    where rank>1
    )

    alter table MyTable 
    drop  column sno
1
16.12.2015 06:11:51

Теперь давайте посмотрим таблицу elasticalsearch, в которой в этих таблицах есть дублирующиеся строки, а Id - это идентичное поле uniq. Мы знаем, если какой-то идентификатор существует по групповым критериям, тогда мы можем удалить другие строки вне этой группы. Моя манера показывает этот критерий.

Так много случаев этой темы находятся в моем подобном состоянии. Просто измените критерии целевой группы в соответствии с вашим случаем удаления повторяющихся (дублированных) строк.

DELETE 
FROM elasticalsearch
WHERE Id NOT IN 
               (SELECT min(Id)
                     FROM elasticalsearch
                     GROUP BY FirmId,FilterSearchString
                     ) 

ура

0
25.01.2016 14:33:23
Не могли бы вы объяснить, как / почему ваш код работает? Это позволит ОП и другим лицам понять и применить ваши методы (где это применимо) в других местах. Ответы только на код не рекомендуется и могут быть удалены. - Во время обзора
Wai Ha Lee 18.01.2016 23:51:45
Хорошо, я объяснил, что мой ответчик Вай Ха Ли, вдохновляющий код, показывает все детали
Hamit YILDIRIM 19.01.2016 07:15:47