Як видалити дублікати з таблиці MySQL?


158

Мені потрібно DELETEдублювати рядки для вказаного sid на aMySQL столі.

Як я можу це зробити за допомогою SQL-запиту?

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

Щось подібне, але я не знаю, як це зробити.


Вам це потрібно робити лише один раз чи потрібно це робити постійно?
Біллі ONeal

Чи всі записи з повторюваними записами мають однакові дані, чи всі інші поля відрізняються один від одного? Якщо у вас є перший варіант, ви можете просто видалити всі записи, окрім одного, якщо у вас є другий варіант, як визначити, яку запис потрібно зберігати?
rael_kid

@Lex Перший варіант. @Billy мені потрібно це робити постійно.
Алі Демірці


1
Є багато речей, які змінилися тут у різних версіях MySQL. Уважно перевірте свою версію MySQL, перш ніж стрибати вниз по шляху будь-якого з тут рішень.
delatbabel

Відповіді:


215

це видаляє дублікати на місці, не створюючи нової таблиці

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

Примітка: добре працює лише в тому випадку, якщо індекс вписується в пам'ять


26
Зверніть увагу: це дозволило б зберегти найдавнішу копію дублікатів і видалити новіші. Якщо ви хочете зберегти новітні, ви не можете цього зробити ALTER IGNORE.
Харалан Добрев

9
Схоже, це не працює з InnoDB. Я побіг ALTER TABLE foo ENGINE MyISAMпрацювати навколо цього, після змінив двигун.
Мартін

13
це може вийти з ладу на MySQL> 5.5, якщо так використовувати "встановити сеанс old_alter_table = 1;" та "встановити сеанс old_alter_table = 0;" до і після виступу
chillitom


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  

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 / ... Ви могли б також ризикувати видалення деяких рядків інших таблиць відносяться, але ви можете контролювати , які записи обрані в deduped таблиць шляхом зміни запиту 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     | 
    # +-----+------+----------+ 

Максимальний агрегат працює на новому індексі му:

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. Це відповідає лівій таблиці "a". (foo, bar, baz) зліва має кожен рядок таблиці. Права підмножина 'b' має (maxtimestamp, foo, bar), яка відповідає лівій лише тій, що IS max.

Кожен рядок, який не є таким, має значення maxxtimetamp NULL. Відфільтруйте ці рядки NULL, і у вас є набір усіх рядків, згрупованих по футу та смузі, що не є останнім базовим позначенням часових позначок. Видаліть ці.

Зробіть резервну копію таблиці, перш ніж це запустити.

Не дозволяйте цій проблемі повторюватися на цій таблиці:

Якщо ви змусили це працювати, і він випустив ваш "повторюваний рядок" пожежі. Чудово. Тепер визначте новий складний унікальний ключ на вашій таблиці (у цих двох стовпцях), щоб унеможливити додавання більше дублікатів.

Як і хороша імунна система, погані ряди навіть не слід пускати до столу під час вставки. Пізніше всі ці програми, що додають дублікати, будуть висловлювати свій протест, і коли ви їх виправите, ця проблема ніколи не з’явиться знову.


6
ставка суто за мадагаскарську довідку!
Майкл Віггінс

1
Оцінений, оскільки це чудова відповідь і чудові пропозиції, дякую, Ерік працював краще, ніж будь-яка інша відповідь там.
Джохан

4
Примітка: Якщо у вашій таблиці є IDстовпець з автоматичним збільшенням, тоді цей ONпункт повинен відповідати лише IDстовпцю, нічого іншого.
ebyrob

1
Мені подобається детальне пояснення, але ... Якщо я правильно розумію, ця відповідь використовує часову позначку, щоб розрізняти записи. У цьому сенсі записи не дублюються. Що робити, якщо у вас не було позначки часу для розмежування записів, тобто всі команди однакові для 2 або більше записів?
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);

Єдине застереження - це те, що мені доводиться запускати запит кілька разів, але навіть маючи це, я виявив, що він працює для мене краще, ніж інші варіанти.


1
Прагматичне рішення! Працювало для мене - близько 20-х років для 2m + рядка innodb таблиці. Одного разу я використав його кілька разів і зводився до кількох порушників з великою кількістю дублікатів, закінчив роботу вручну.
Troy Wray

1
Працював для мене в один загін, приголомшливий!
Мурва

Він повинен бути виконаний кілька разів, якщо дублікатів для будь-яких стовпців більше, ніж 2x
PayteR

@PayteR, що сказано у відповіді, "Єдине застереження - це те, що мені потрібно запустити запит кілька разів"
seaders

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, неможливо створити жодних повторюваних записів на основі цих двох полів.


1
Ви не знадобилися б ORDER BYв , SELECTщоб бути впевненими , яка запис на насправді робить його більш до NoDupeTable?
ebyrob

@ebyrob Я вірю, якщо інше не буде прописано, він вибере найнижчий ідентифікатор за відсутності інших критеріїв. Звичайно, ORDER by ID Ascне могло зашкодити, тому я все-таки редагую свою відповідь.
user3649739

@ebyrob Вибачте мене погано. Наскільки я не знаю, замовлення не буде працювати в цьому виді. Порядок від в кінці вибору буде впорядковувати лише дублікати, знайдені найнижчим ідентифікатором, знайденим у кожній парі. Крім того, ви можете зробити a, Select Max(ID)а потім, Order by Max(ID)але все, що буде зроблено, це змінити порядок вставки. Для отримання найвищого ідентифікатора знадобиться, я вважаю, що більш складний вибір приєднається як, незалежно від того, як ви замовляєте вище, ви будете захоплювати значення поля з нижнього ідентифікатора.
user3649739

Власне, не впевнений, що я думав із замовленням. Ви б точно хочете MAX(ID)або MIN(ID)й імена стовпців замість *в SELECT FROM DupeTableХоча, в іншому випадку ви просто отримаєте один з ID«S випадковим чином . Насправді багато SQL і навіть строгий MySQL вимагають викликати сукупну функцію в кожному стовпчику, не вказаному в GROUP BYпункті.
ebyrob

@ebyrob При тестуванні Max (ID) Min (ID) нічого не робити, окрім повернення ідентифікатора запису Max або Mind. У кожному випадку відбирає однакові записи. Отже, якби у мене було два записи з полями ID,First,Last,Notesі записами, 1,Bob,Smith,NULLа 2,Bob,Smith,Arrearsпотім виконання 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` ;

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), щоб видалити новіші записи.


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;

1
Я виявив, що набагато ефективніше рішення, ніж вище,
Крістіан Буцке

5

Я вважаю, що рішення Вернера вище є найзручнішим, оскільки воно працює незалежно від наявності первинного ключа, не псується з таблицями, використовує непрозорі майбутні sql, дуже зрозуміло.

Як я зазначив у своєму коментарі, це рішення не було належним чином пояснено. Отже, це моє, виходячи з цього.

1) додати новий булевий стовпчик

alter table mytable add tokeep boolean;

2) додати обмеження на дублювані стовпці ТА новий стовпець

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

3) встановити булеву колонку в істинне. Це вдасться досягти лише в одному з дублюваних рядків через нове обмеження

update ignore mytable set tokeep = true;

4) видалити рядки, які не були позначені як зйомка

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:

Ви повинні використовувати індекс на одному або декількох стовпцях (тип індексу). Створіть новий тимчасовий довідковий стовпчик (не частина індексу). У цьому стовпці ви позначаєте unique, оновляючи його за допомогою ігнорування. Крок за кроком:

Додайте тимчасовий довідковий стовпчик для позначення унікальних даних:

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= 'Так' ніколи не вийде з ладу.
xtian

Також пам’ятайте, що 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)зберегти останній екземпляр замість першого.


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 * зі старого імені;

Порожній ваш оригінальний стіл

ВИДАЛИТИ * від старого імені;

Копіює всі окремі значення з скопійованої таблиці назад у початкову таблицю

ВСТАВИТИ oldtablename SELECT * з групи temp_table за іменем, прізвищем, dob

Видаляє таблицю темп.

Таблиця викидання temp_table

Вам потрібно згрупуватися за полями aLL, які ви хочете виділити.


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, щоб вибрати список "очищений" (і ось дуже простий приклад того, як це зробити).


Як це відповідає на питання? Використовуючи DISTINCTви втрачаєте будь-яку інформацію про дублікати, яка, можливо, у вас була в першу чергу. Чи можете ви показати спосіб видалення дублікатів за допомогою нього?
luk2302

-3

Чи може це працювати, якщо ви порахуєте їх, а потім додасте обмеження до запиту на видалення, залишивши лише один?

Наприклад, якщо у вас є дві або більше, напишіть свій запит так:

DELETE FROM table WHERE SID = 1 LIMIT 1;

-5

Для видалення дублікатів даних із таблиці є лише кілька основних кроків:

  • Завантажте резервний стіл!
  • Знайдіть повторювані рядки
  • Видаліть повторювані рядки

Ось повний підручник: https://blog.teamsql.io/deleting-duplicate-data-3541485b3473


Чи працює, якщо тільки унікальний ідентифікатор відрізняється. Eğer sadece benzersiz id farklı ise de bu işe yarar mı?
Андрій

За замовчуванням описаний тут метод не працює для версій MySQL> 5.7.5. Це через обробку ONLY_FULL_GROUP_BY. Дивіться тут: dev.mysql.com/doc/refman/5.7/uk/group-by-handling.html
delatbabel
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.