Как удалить дубликаты в таблице MySQL?

158

Мне нужно DELETEдублировать строки для указанного SID наMySQL таблице.

Как я могу сделать это с запросом SQL?

DELETE (DUPLICATED TITLES) FROM table WHERE SID = "1"

Как то так, но я не знаю как это сделать.

Али Демирчи
источник
Вам нужно сделать это только один раз или вам нужно делать это все время?
Билли ONEAL
Все ли записи с повторяющимися записями имеют одинаковые данные, или остальные поля отличаются друг от друга? Если у вас есть первый вариант, вы можете просто удалить все записи, кроме одного, если у вас есть второй вариант, как вы определяете, какую запись вы хотите сохранить?
rael_kid
@Lex Первый вариант. @ Билли, мне нужно все время это делать.
Али Демирчи
1
возможный дубликат удаления повторяющихся строк в MySQL
Basilevs
1
Есть много вещей, которые изменились здесь в различных версиях MySQL. Внимательно проверьте свою версию MySQL, прежде чем переходить к какому-либо из решений здесь.
delatbabel

Ответы:

215

это удаляет дубликаты на месте, не создавая новую таблицу

ALTER IGNORE TABLE `table_name` ADD UNIQUE (title, SID)

примечание: хорошо работает, только если индекс помещается в память

user187291
источник
26
Обратите внимание: это сохранит самую старую дубликатную запись и сотрет новые. Если вы хотите сохранить новейшие, вы не можете сделать это с ALTER IGNORE.
Харалан Добрев
9
Кажется, не работает с InnoDB. Я побежал ALTER TABLE foo ENGINE MyISAMобойти это, поменял двигатель обратно после.
Мартин
13
это может не сработать на MySQL> 5.5, если так, используйте «set session old_alter_table = 1;» и "установить сессию old_alter_table = 0;" до и после заявления
чиллитом
2
@delatbabel Причина, по которой он устарел, указана на странице, на которую вы ссылаетесь.
Бармар
133

Предположим, у вас есть таблица employeeсо следующими столбцами:

employee (first_name, last_name, start_date)

Чтобы удалить строки с дублирующимся first_nameстолбцом:

delete
from employee using employee,
    employee e1
where employee.id > e1.id
    and employee.first_name = e1.first_name  
Abhijoy_D
источник
1
Оставшаяся запись будет иметь максимальный или минимальный идентификатор в своей дублирующей группе?
Замороженное пламя
Оставшаяся запись будет иметь минимальный идентификатор, поскольку она является единственной, не соответствующей условию удаления
Пабло Герреро,
1
Похоже, что объединение employeeпротив себя для одного совпадения индекса и одна >проверка индекса будет медленным для больших таблиц. Разве не было бы лучше, SELECT MAX(ID) FROM t GROUP BY uniqueа затем JOINточное совпадение IDс MAX(ID)?
ebyrob
1
Отличный ответ! Сэкономил мое время!
Несар
56

После удаления дубликатов для всех SID-ов, а не только одного.

С временной таблицей

CREATE TABLE table_temp AS
SELECT * FROM table GROUP BY title, SID;

DROP TABLE table;
RENAME TABLE table_temp TO table;

Поскольку temp_tableон только что создан, он не имеет индексов. Вам нужно будет воссоздать их после удаления дубликатов. Вы можете проверить, какие индексы у вас есть в таблице сSHOW INDEXES IN table

Без временной таблицы:

DELETE FROM `table` WHERE id IN (
  SELECT all_duplicates.id FROM (
    SELECT id FROM `table` WHERE (`title`, `SID`) IN (
      SELECT `title`, `SID` FROM `table` GROUP BY `title`, `SID` having count(*) > 1
    )
  ) AS all_duplicates 
  LEFT JOIN (
    SELECT id FROM `table` GROUP BY `title`, `SID` having count(*) > 1
  ) AS grouped_duplicates 
  ON all_duplicates.id = grouped_duplicates.id 
  WHERE grouped_duplicates.id IS NULL
)
Камил Шот
источник
4
GROUP-ing создает только одну строку результатов для каждой комбинации значений полей, по которым вы группируете. Так что дубликаты будут удалены.
Камил Сзот
4
Мне нравится первый способ, здесь слишком элегантно! : B
AgelessEssence
1
@fiacre Вы можете временно отключить проверку внешнего ключа: stackoverflow.com/questions/15501673/… Возможно, вы также рискуете удалить некоторые строки, на которые ссылаются другие таблицы, но вы можете контролировать, какие записи выбираются в дедуплицированную таблицу, изменяя запрос SELECT * FROM table GROUP BY title, SID;Все зависит от того, насколько хорошо вы знаете, что делаете.
Камил Сзот
1
@ahnbizcad Вы можете использовать временную таблицу, но тогда вам придется скопировать данные обратно из временной таблицы в обычную таблицу. Если вы используете реальную таблицу, вы можете просто отбросить старую таблицу с дубликатами и переименовать новую, без дубликата на имя старого.
Камил Сзот
1
Метод «без временной таблицы» наиболее близок к лучшему решению, однако остерегайтесь обработки ONLY_FULL_GROUP_BY, которая изменилась в MySQL 5.7.5: dev.mysql.com/doc/refman/5.7/en/group-by-handling.html Я получил это работать, заменив «SELECT id» на «SELECT ANY_VALUE (id) AS id»
delatbabel
53

Удаление дублирующихся строк в MySQL на месте, (при условии, что у вас есть столбец метки времени для сортировки) пошаговое руководство:

Создайте таблицу и вставьте несколько строк:

create table penguins(foo int, bar varchar(15), baz datetime);
insert into penguins values(1, 'skipper', now());
insert into penguins values(1, 'skipper', now());
insert into penguins values(3, 'kowalski', now());
insert into penguins values(3, 'kowalski', now());
insert into penguins values(3, 'kowalski', now());
insert into penguins values(4, 'rico', now());
select * from penguins;
    +------+----------+---------------------+
    | foo  | bar      | baz                 |
    +------+----------+---------------------+
    |    1 | skipper  | 2014-08-25 14:21:54 |
    |    1 | skipper  | 2014-08-25 14:21:59 |
    |    3 | kowalski | 2014-08-25 14:22:09 |
    |    3 | kowalski | 2014-08-25 14:22:13 |
    |    3 | kowalski | 2014-08-25 14:22:15 |
    |    4 | rico     | 2014-08-25 14:22:22 |
    +------+----------+---------------------+
6 rows in set (0.00 sec)

Удалить дубликаты на месте:

delete a
    from penguins a
    left join(
    select max(baz) maxtimestamp, foo, bar
    from penguins
    group by foo, bar) b
    on a.baz = maxtimestamp and
    a.foo = b.foo and
    a.bar = b.bar
    where b.maxtimestamp IS NULL;
Query OK, 3 rows affected (0.01 sec)
select * from penguins;
+------+----------+---------------------+
| foo  | bar      | baz                 |
+------+----------+---------------------+
|    1 | skipper  | 2014-08-25 14:21:59 |
|    3 | kowalski | 2014-08-25 14:22:15 |
|    4 | rico     | 2014-08-25 14:22:22 |
+------+----------+---------------------+
3 rows in set (0.00 sec)

Все готово, повторяющиеся строки удаляются, последняя отметка времени сохраняется.

Для тех из вас, у кого нет метки времени или уникальной колонки.

У вас нет timestampили уникальный индексный столбец для сортировки? Вы живете в состоянии вырождения. Вам придется сделать дополнительные шаги, чтобы удалить дубликаты строк.

создать таблицу пингвинов и добавить несколько строк

create table penguins(foo int, bar varchar(15)); 
insert into penguins values(1, 'skipper'); 
insert into penguins values(1, 'skipper'); 
insert into penguins values(3, 'kowalski'); 
insert into penguins values(3, 'kowalski'); 
insert into penguins values(3, 'kowalski'); 
insert into penguins values(4, 'rico'); 
select * from penguins; 
    # +------+----------+ 
    # | foo  | bar      | 
    # +------+----------+ 
    # |    1 | skipper  | 
    # |    1 | skipper  | 
    # |    3 | kowalski | 
    # |    3 | kowalski | 
    # |    3 | kowalski | 
    # |    4 | rico     | 
    # +------+----------+ 

сделать клон первой таблицы и скопировать в нее.

drop table if exists penguins_copy; 
create table penguins_copy as ( SELECT foo, bar FROM penguins );  

#add an autoincrementing primary key: 
ALTER TABLE penguins_copy ADD moo int AUTO_INCREMENT PRIMARY KEY first; 

select * from penguins_copy; 
    # +-----+------+----------+ 
    # | moo | foo  | bar      | 
    # +-----+------+----------+ 
    # |   1 |    1 | skipper  | 
    # |   2 |    1 | skipper  | 
    # |   3 |    3 | kowalski | 
    # |   4 |    3 | kowalski | 
    # |   5 |    3 | kowalski | 
    # |   6 |    4 | rico     | 
    # +-----+------+----------+ 

Максимальный агрегат работает с новым индексом moo:

delete a from penguins_copy a left join( 
    select max(moo) myindex, foo, bar 
    from penguins_copy 
    group by foo, bar) b 
    on a.moo = b.myindex and 
    a.foo = b.foo and 
    a.bar = b.bar 
    where b.myindex IS NULL; 

#drop the extra column on the copied table 
alter table penguins_copy drop moo; 
select * from penguins_copy; 

#drop the first table and put the copy table back: 
drop table penguins; 
create table penguins select * from penguins_copy; 

наблюдать и убирать

drop table penguins_copy; 
select * from penguins;
+------+----------+ 
| foo  | bar      | 
+------+----------+ 
|    1 | skipper  | 
|    3 | kowalski | 
|    4 | rico     | 
+------+----------+ 
    Elapsed: 1458.359 milliseconds 

Что делает этот большой оператор удаления SQL?

Настольные пингвины с псевдонимом «a» оставляются соединенными с подмножеством настольных пингвинов, которое называется «b». Правая таблица 'b', которая является подмножеством, находит метку максимального времени [или max moo], сгруппированную по столбцам foo и bar. Это соответствует левой таблице «а». (foo, bar, baz) слева имеет каждую строку в таблице. Правое подмножество 'b' имеет (maxtimestamp, foo, bar), которое соответствует левому только тому, которое является макс.

Каждая строка, отличная от max, имеет значение maxtimestamp, равное NULL. Отфильтруйте эти NULL-строки, и у вас будет набор всех строк, сгруппированных по foo и bar, который не является последней базой меток времени. Удалить те.

Сделайте резервную копию таблицы, прежде чем запускать это.

Предотвратите повторение этой проблемы за этим столом:

Если вы заставили это сработать, и это потушило ваш «двойной ряд» огня. Отлично. Теперь определите новый составной уникальный ключ в вашей таблице (в этих двух столбцах), чтобы предотвратить добавление новых дубликатов.

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

Эрик Лещинский
источник
6
Оцените чисто для справки Мадагаскара!
Майкл Уиггинс
1
Оценил, так как это отличный ответ, и отличные предложения, спасибо, Эрик работал лучше, чем любой другой ответ там.
Йохан
4
Примечание. Если в вашей таблице есть IDстолбец с автоинкрементом, то это ONпредложение должно соответствовать только IDстолбцу, и ничего больше.
ebyrob
1
Мне нравится подробное объяснение, но ... Если я правильно понимаю, этот ответ использует метку времени, чтобы различать записи. В этом смысле записи не являются дубликатами. Что если у вас не было метки времени, чтобы различать записи, т.е. все столбцы одинаковы для двух или более записей?
Rsc Rsc
1
@RscRsc Если у вас нет столбца метки времени или уникального индекса для применения максимальной совокупности, то похоже, что вам нужно дублировать таблицу, добавить уникальный индекс, применить оператор удаления, а затем заменить скопированную таблицу обратно на исходную. , Я изменил ответ, чтобы отразить эти инструкции.
Эрик Лещинский
16

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

В операторе с одним запросом, без временной таблицы, это работало лучше всего для меня,

DELETE e.*
FROM employee e
WHERE id IN
 (SELECT id
   FROM (SELECT MIN(id) as id
          FROM employee e2
          GROUP BY first_name, last_name
          HAVING COUNT(*) > 1) x);

Единственное предостережение в том, что я должен выполнить запрос несколько раз, но даже при этом я обнаружил, что он работает лучше для меня, чем другие варианты.

seaders
источник
1
Прагматичное решение! Работал для меня - около 20 с для таблицы innodb 2m + строки. Однажды я использовал его несколько раз, и до нескольких преступников с большим количеством дубликатов закончил работу вручную.
Трой Рэй
1
Работал на меня одним махом, потрясающе!
Мурва
Он должен выполняться несколько раз, если дубликаты для каких-либо столбцов превышают 2x
PayteR
@PayteR, который указан в ответе: «Единственное предостережение в том, что я должен выполнить запрос несколько раз»,
моряки
13

Кажется, это всегда работает для меня:

CREATE TABLE NoDupeTable LIKE DupeTable; 
INSERT NoDupeTable SELECT * FROM DupeTable group by CommonField1,CommonFieldN;

Который сохраняет наименьший идентификатор для каждого из дупсов и остальных записей не дуплей.

Я также предпринял следующие действия, чтобы проблема удаления больше не возникала после удаления:

CREATE TABLE NoDupeTable LIKE DupeTable; 
Alter table NoDupeTable Add Unique `Unique` (CommonField1,CommonField2);
INSERT IGNORE NoDupeTable SELECT * FROM DupeTable;

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

Перемещение fwd становится невозможным для создания дубликатов записей на основе этих двух полей.

user3649739
источник
1
Разве вы не нуждаетесь ORDER BYв, SELECTчтобы быть уверенным, какая запись на самом деле переходит на NoDupeTable?
ebyrob
@ebyrob Я думаю, если не указано иное, он выберет самый низкий идентификатор в отсутствие других критериев. Конечно, ORDER by ID Ascне повредит, поэтому я все же отредактирую свой ответ.
user3649739
@ebyrob Извините, мой плохой. Насколько мне известно, Order by не будет работать в этом списке. При заказе в конце выбора будут упорядочены только дубликаты, найденные по наименьшему идентификатору, найденному в каждой паре. Поочередно вы можете сделать a, Select Max(ID)а затем, Order by Max(ID)но все, что нужно сделать, это изменить порядок вставки. Для получения самого высокого идентификатора потребуется, по-моему, более сложное соединение выбора, поскольку независимо от того, как вы заказываете выше, вы будете получать значения полей из более низкого идентификатора.
user3649739
На самом деле, не уверен, что я думал с заказом. Вы бы определенно хотели MAX(ID)или MIN(ID)и имена столбцов, а не *в SELECT FROM DupeTableхотя, в противном случае вы просто получите один из IDслучайных. Фактически, многие SQL и даже строгие требования MySQL требуют вызова статистической функции для каждого столбца, не указанного в GROUP BYпредложении.
ebyrob
@ebyrob При тестировании Max (ID) Min (ID) ничего не делать, кроме как вернуть ID записи Max или Mind. В каждом случае захватывает одни и те же записи. Поэтому, если бы у меня было две записи с полями ID,First,Last,Notesи записями, 1,Bob,Smith,NULLа 2,Bob,Smith,Arrearsзатем выполнение a SELECT *Max(ID), First,Last,Notes FROM DupeTable group by First,Lastвернуло бы одну и ту же запись, 1, за исключением другого идентификатора. Max (ID) вернется, 2,Bob,Smith,NULLа Min (ID) вернется 1,Bob,Smith,NULL. Я считаю, что для получения второй записи с "Задолженностью" в примечаниях требуется объединение.
user3649739
7

Следующие работы для всех таблиц

CREATE TABLE `noDup` LIKE `Dup` ;
INSERT `noDup` SELECT DISTINCT * FROM `Dup` ;
DROP TABLE `Dup` ;
ALTER TABLE `noDup` RENAME `Dup` ;
MBMiri
источник
6

Вот простой ответ:

delete a from target_table a left JOIN (select max(id_field) as id, field_being_repeated  
    from target_table GROUP BY field_being_repeated) b 
    on a.field_being_repeated = b.field_being_repeated
      and a.id_field = b.id_field
    where b.id_field is null;
Тед Селестин
источник
Это хороший ответ, за исключением небольшой ошибкиand a.id_field = b.id
Викрант Гоэль
LEFT JOINК bтолько нужно сравнить b.id= a.id_fieldпредполагая field_idуникальную автоматическое приращение ID. так a.field_being_repeated = b.field_being_repeatedпосторонний. (также b.id_fieldне существует в этом запросе это b.id.
ebyrob
6

Эта работа для меня, чтобы удалить старые записи:

delete from table where id in 
(select min(e.id)
    from (select * from table) e 
    group by column1, column2
    having count(*) > 1
); 

Вы можете заменить min (e.id) на max (e.id), чтобы удалить новейшие записи.

richardhell
источник
5
delete p from 
product p
inner join (
    select max(id) as id, url from product 
    group by url 
    having count(*) > 1
) unik on unik.url = p.url and unik.id != p.id;
temonehm
источник
1
Я обнаружил, что гораздо более производительное решение, чем приведенное выше,
Кристиан Бутцке,
5

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

Как я сказал в своем комментарии, это решение не было должным образом объяснено все же. Так что это мое, основываясь на этом.

1) добавить новый логический столбец

alter table mytable add tokeep boolean;

2) добавить ограничение на дублированные столбцы и новый столбец

alter table mytable add constraint preventdupe unique (mycol1, mycol2, tokeep);

3) установите для логического столбца значение true. Это будет успешным только в одной из дублированных строк из-за нового ограничения

update ignore mytable set tokeep = true;

4) удалить строки, которые не были помечены как tokeep

delete from mytable where tokeep is null;

5) опустить добавленный столбец

alter table mytable drop tokeep;

Я предлагаю, чтобы вы сохранили ограничение, которое вы добавили, чтобы новые дубликаты были предотвращены в будущем.

кстианской
источник
4

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

Надеюсь, это кому-нибудь пригодится.

DROP TABLE IF EXISTS UniqueIDs;
CREATE Temporary table UniqueIDs (id Int(11));

INSERT INTO UniqueIDs
    (SELECT T1.ID FROM Table T1 LEFT JOIN Table T2 ON
    (T1.Field1 = T2.Field1 AND T1.Field2 = T2.Field2 #Comparison Fields 
    AND T1.ID < T2.ID)
    WHERE T2.ID IS NULL);

DELETE FROM Table WHERE id NOT IN (SELECT ID FROM UniqueIDs);
Саймон
источник
4

Еще один простой способ ... с помощью UPDATE IGNORE:

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

Добавьте временный справочный столбец, чтобы отметить уникальность:

ALTER TABLE `yourtable` ADD `unique` VARCHAR(3) NOT NULL AFTER `lastcolname`;

=> это добавит столбец к вашей таблице.

Обновите таблицу, попробуйте пометить все как уникальные, но игнорируйте возможные ошибки из-за дублирования ключа (записи будут пропущены):

UPDATE IGNORE `yourtable` SET `unique` = 'Yes' WHERE 1;

=> вы обнаружите, что ваши повторяющиеся записи не будут помечены как уникальные = 'Да', другими словами, только одна из каждого набора повторяющихся записей будет помечена как уникальная.

Удалите все, что не уникально:

DELETE * FROM `yourtable` WHERE `unique` <> 'Yes';

=> Это удалит все дубликаты записей.

Оставьте столбец ...

ALTER TABLE `yourtable` DROP `unique`;
Вернер
источник
Я думаю, что это лучшее решение, потому что оно не связывается с таблицами и использует простой простой sql. Должно быть ясно только одно: uniqueстолбец ДОЛЖЕН быть добавлен к уникальному ограничению вместе со столбцами, которые в настоящее время дублируются, иначе все это не будет работать, потому что SET unique= 'Yes' никогда не завершится ошибкой.
августа
Также имейте uniqueв виду, что это ключевое слово mysql. Таким образом, он должен иметь галочки (как уже правильно отображается). Использование другого слова для столбца может быть более удобным.
Торстен
2

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

Али , в вашем случае вы можете запустить что-то вроде этого:

-- create a new temporary table
CREATE TABLE tmp_table1 LIKE table1;

-- add a unique constraint    
ALTER TABLE tmp_table1 ADD UNIQUE(sid, title);

-- scan over the table to insert entries
INSERT IGNORE INTO tmp_table1 SELECT * FROM table1 ORDER BY sid;

-- rename tables
RENAME TABLE table1 TO backup_table1, tmp_table1 TO table1;
Цезарь Реверт-Гомар
источник
0
delete from `table` where `table`.`SID` in 
    (
    select t.SID from table t join table t1 on t.title = t1.title  where t.SID > t1.SID
)
Патрик
источник
Это приводит к ошибке SQL (1093) в некоторых конфигурациях и версиях MySQL.
ebyrob
0

Ответ Love @ eric, но, кажется, он не работает, если у вас действительно большой стол (я получаю, The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okayкогда пытаюсь его запустить). Поэтому я ограничил запрос на соединение только рассмотрением дублирующихся строк и в итоге получил:

DELETE a FROM penguins a
    LEFT JOIN (SELECT COUNT(baz) AS num, MIN(baz) AS keepBaz, foo
        FROM penguins
        GROUP BY deviceId HAVING num > 1) b
        ON a.baz != b.keepBaz
        AND a.foo = b.foo
    WHERE b.foo IS NOT NULL

Предложение WHERE в этом случае позволяет MySQL игнорировать любую строку, у которой нет дубликата, а также игнорирует, если это первый экземпляр дубликата, поэтому будут игнорироваться только последующие дубликаты. Перейдите MIN(baz)на MAX(baz)сохранение последнего экземпляра вместо первого.

Gujamin
источник
0

Это работает для больших таблиц:

 CREATE Temporary table duplicates AS select max(id) as id, url from links group by url having count(*) > 1;

 DELETE l from links l inner join duplicates ld on ld.id = l.id WHERE ld.id IS NOT NULL;

Удалить самое старое изменение max(id)наmin(id)

Мугома Дж. Окомба
источник
0

Это здесь сделает столбец column_nameпервичным ключом, а тем временем проигнорирует все ошибки. Таким образом, будут удалены строки с повторяющимся значением для column_name.

ALTER IGNORE TABLE `table_name` ADD PRIMARY KEY (`column_name`);
Авраам Мурчиано Бензадон
источник
Как отмечено в комментариях к предыдущему ответу, это больше не работает в 5.7.
Бармар
0

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

Создает точную копию вашего стола

создать таблицу temp_table как oldtablename; вставить temp_table select * from oldtablename;

Опорожняет ваш оригинальный стол

УДАЛИТЬ * от oldtablename;

Копирует все отдельные значения из скопированной таблицы обратно в исходную таблицу

ВСТАВИТЬ oldtablename SELECT * из группы temp_table по имени, фамилии, dob

Удаляет вашу временную таблицу.

Удалить таблицу temp_table

Вам нужно сгруппировать по всем полям, которые вы хотите сохранить отдельно.

ChrisAardvark
источник
0
DELETE T2
FROM   table_name T1
JOIN   same_table_name T2 ON (T1.title = T2.title AND T1.ID <> T2.ID)
навигационный
источник
не работает ваш запрос, пожалуйста, не могли бы вы улучшить его?
Самир Гидрк
0

вот как я обычно устраняю дубликаты

  1. добавить временный столбец, назовите его как хотите (я буду называть активным)
  2. сгруппируйте по полям, которые, по вашему мнению, не должны дублироваться, и установите для них значение «1»; при группировании по этим столбцам будет выбрано только одно из дублированных значений (не будут выбраны дубликаты).
  3. удалить те с активным нулем
  4. активный столбец
  5. по желанию (если подходит для ваших целей), добавьте уникальный индекс для этих столбцов, чтобы больше не иметь дубликатов
Язган
источник
-2

Вы можете просто использовать предложение DISTINCT, чтобы выбрать «очищенный» список (и вот очень простой пример того, как это сделать).

Rosamunda
источник
Как это отвечает на вопрос? Используя DISTINCTвас, вы потеряете любую информацию о дубликатах, которые у вас могли быть. Можете ли вы показать способ удаления дубликатов, используя его?
luk2302
-3

Может ли это сработать, если вы посчитаете их, а затем добавите ограничение к вашему запросу на удаление, оставив только один?

Например, если у вас есть два или более, напишите ваш запрос следующим образом:

DELETE FROM table WHERE SID = 1 LIMIT 1;
user3325657
источник
-5

Существует всего несколько основных шагов при удалении дублирующихся данных из вашей таблицы:

  • Сделай резервную копию своего стола!
  • Найти дубликаты строк
  • Удалить повторяющиеся строки

Вот полный учебник: https://blog.teamsql.io/deleting-duplicate-data-3541485b3473

Жестяная банка
источник
Работает ли, если только уникальный идентификатор отличается. Когда ты идешь к нам?
Андрей
По умолчанию метод, описанный здесь, не работает для версий MySQL> 5.7.5. Это из-за обработки ONLY_FULL_GROUP_BY. Смотрите здесь: dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
delatbabel