Как удалить повторяющиеся строки и сохранить первую строку?

Я допустил ошибку, и у меня есть нежелательные дубликаты.

У меня есть таблица с 4 ключевыми полями. A1, k1, k2, k3.

A1 - это автоматический приращение и первичный ключ.

комбинация k1, k2 и k3 должна быть уникальной, и я должен удалить повторяющиеся строки до создания уникального индекса. Некоторые строки имеют один дубликат, некоторые из них имеют много.

SELECT CONCAT(k1, k2, k) AS dup_value
  FROM myviews
 GROUP BY dup_value
HAVING (COUNT(dup_value) > 1)

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

Ответ 1

Резервное копирование данных, затем...

MySQL поддерживает JOINs в операторах DELETE. Если вы хотите сохранить первый дубликат:

DELETE a
  FROM MYVIEWS a
  JOIN (SELECT MIN(t.a1) AS min_a1, t.k1, t.k2, t.k3
          FROM MYVIEWS t
      GROUP BY t.k1, t.k2, t.k3
        HAVING COUNT(*) > 1) b ON b.k1 = a.k1
                              AND b.k2 = a.k2
                              AND b.k3 = a.k3
                              AND b.min_a1 != a.a1

Если вы хотите сохранить последний дубликат:

DELETE a
  FROM MYVIEWS a
  JOIN (SELECT MAX(t.a1) AS max_a1, t.k1, t.k2, t.k3
          FROM MYVIEWS t
      GROUP BY t.k1, t.k2, t.k3
        HAVING COUNT(*) > 1) b ON b.k1 = a.k1
                              AND b.k2 = a.k2
                              AND b.k3 = a.k3
                              AND b.max_a1 != a.a1

Ответ 2

Вы можете создать новую таблицу с той же структурой, но пустую, затем создать на ней уникальный ключ, затем сделать INSERT IGNORE/SELECT * FROM исходную таблицу в новую таблицу, а затем удалить исходную таблицу.

INSERT IGNORE автоматически игнорирует любые первичные или уникальные ключевые проблемы и просто пропускает дубликаты.

Ответ 3

Что-то подобное?

DELETE FROM myviews WHERE EXISTS(SELECT CONCAT(k1, k2, k) AS dup_value
FROM myviews
GROUP BY dup_value
HAVING (COUNT(dup_value) > 1));

Ответ 4

Вам нужен разделитель в вашей функции concat, потому что иначе "a", "b" и "cd" будут такими же, как "abcd", "," ".