У меня есть таблица со следующими полями:
id (Unique)
url (Unique)
title
company
site_id
Теперь мне нужно удалить строки, имеющие одинаковые title, company and site_id
. Один из способов сделать это будет использовать следующий SQL вместе со скриптом ( PHP
):
SELECT title, site_id, location, id, count( * )
FROM jobs
GROUP BY site_id, company, title, location
HAVING count( * ) >1
После выполнения этого запроса я могу удалить дубликаты, используя скрипт на стороне сервера.
Но я хочу знать, если это можно сделать только с помощью SQL-запроса.
mysql
sql
duplicates
Четан
источник
источник
Ответы:
Действительно простой способ сделать это - добавить
UNIQUE
индекс по 3 столбцам. Когда вы пишетеALTER
заявление, включитеIGNORE
ключевое слово. Вот так:Это удалит все дубликаты строк. Как дополнительное преимущество, будущие,
INSERTs
которые являются дубликатами, будут ошибаться. Как всегда, вы можете сделать резервную копию, прежде чем запускать что-то вроде этого ...источник
set session old_alter_table=1;
Если вы не хотите изменять свойства столбца, используйте запрос ниже.
Поскольку у вас есть столбец с уникальными идентификаторами (например,
auto_increment
столбцы), вы можете использовать его для удаления дубликатов:В MySQL вы можете еще больше упростить его с помощью NULL-безопасного оператора равенства (он же «оператор космического корабля» ):
источник
MySQL имеет ограничения относительно ссылки на таблицу, из которой вы удаляете. Вы можете обойти это с помощью временной таблицы, например:
Из предложения Костаноса в комментариях:
единственный медленный запрос выше - это DELETE, для случаев, когда у вас очень большая база данных. Этот запрос может быть быстрее:
источник
DELETE FROM YourTable USING YourTable, tmpTable WHERE YourTable.id=tmpTable.id
DELETE
, но иINSERT
к временному столу, это заняло у меня много времени. Так что индекс для таблицы tmp может сильно помочь,create index tmpTable_id_index on tmpTable (id)
по крайней мере, для меня.create temporary table tmpTable (id int, PRIMARY KEY (id));
Если
IGNORE
оператор не будет работать так, как в моем случае, вы можете использовать следующий оператор:источник
Удаление дубликатов в таблицах MySQL - это распространенная проблема, которая обычно является результатом отсутствия ограничения, позволяющего избежать этих дубликатов заранее. Но эта общая проблема обычно связана с конкретными потребностями ... которые требуют определенных подходов. Подход должен отличаться в зависимости, например, от размера данных, дублируемой записи, которая должна быть сохранена (обычно первая или последняя), от того, есть ли индексы, которые нужно сохранить, или от того, хотим ли мы выполнить какие-либо дополнительные действия. действие на дублированные данные.
Есть также некоторые особенности самого MySQL, такие как невозможность ссылки на ту же таблицу по причине FROM при выполнении таблицы UPDATE (это вызовет ошибку MySQL # 1093). Это ограничение можно преодолеть, используя внутренний запрос с временной таблицей (как предложено в некоторых подходах выше). Но этот внутренний запрос не будет работать особенно хорошо при работе с большими источниками данных.
Тем не менее, существует лучший подход для удаления дубликатов, он эффективен и надежен, и его можно легко адаптировать к различным потребностям.
Общая идея состоит в том, чтобы создать новую временную таблицу, обычно добавляя уникальное ограничение, чтобы избежать дальнейших дубликатов, и вставлять данные из прежней таблицы в новую, одновременно заботясь о дубликатах. Этот подход основан на простых запросах MySQL INSERT, создает новое ограничение, чтобы избежать дальнейших дубликатов, и пропускает необходимость использования внутреннего запроса для поиска дубликатов и временной таблицы, которая должна храниться в памяти (таким образом, подходя также для больших источников данных).
Вот как это может быть достигнуто. Учитывая, что у нас есть таблица сотрудников , со следующими столбцами:
Чтобы удалить строки с повторяющимся столбцом ssn и сохранить только первую найденную запись, можно выполнить следующий процесс:
Техническое объяснение
⇒ Используя этот подход, 1.6M регистры были преобразованы в 6 КБ менее чем за 200 с.
Четан , следуя этому процессу, вы можете быстро и легко удалить все свои дубликаты и создать УНИКАЛЬНОЕ ограничение, запустив:
Конечно, этот процесс может быть дополнительно изменен, чтобы адаптировать его для различных нужд при удалении дубликатов. Вот несколько примеров.
✔ Вариант для сохранения последней записи вместо первой
Иногда нам нужно сохранить последнюю дублированную запись вместо первой.
✔ Вариант выполнения некоторых задач с дубликатами, например, ведение учета найденных дубликатов.
Иногда нам нужно выполнить некоторую дальнейшую обработку найденных дублированных записей (например, вести подсчет дубликатов).
✔ Вариант для регенерации идентификатора автоинкрементного поля
Иногда мы используем автоинкрементное поле и, чтобы сохранить индекс как можно более компактным, мы можем воспользоваться удалением дубликатов для регенерации автоинкрементного поля в новой временной таблице.
✔ дальнейшие изменения
Многие дополнительные модификации также возможны в зависимости от желаемого поведения. В качестве примера, следующие запросы будут использовать вторую временную таблицу, чтобы, кроме 1) сохранить последнюю запись вместо первой; и 2) увеличить счетчик найденных дубликатов; также 3) восстановить автоматически инкрементный идентификатор поля, сохраняя порядок ввода, как это было на предыдущих данных.
источник
Есть еще одно решение:
источник
Если у вас большая таблица с огромным количеством записей, то вышеприведенные решения не будут работать или занимать слишком много времени. Тогда у нас есть другое решение
источник
У меня есть этот фрагмент запроса для SQLServer, но я думаю, что он может быть использован в других СУБД с небольшими изменениями:
Я забыл сказать, что этот запрос не удаляет строки с наименьшим идентификатором из дублированных строк. Если это работает для вас, попробуйте этот запрос:
источник
ERROR 1093: You can't specify target table 'Table' for update in FROM clause
"You can't specify target table 'Table' for update in FROM..."
ошибку, используйте:,DELETE FROM Table WHERE Table.idTable IN ( SELECT MAX(idTable) FROM (SELECT * FROM idTable) AS tmp GROUP BY field1, field2, field3 HAVING COUNT(*) > 1)
который заставляет MySQL создать временную таблицу. Однако это очень медленно в больших наборах данных ... в таких случаях я буду рекомендовать код Andomar, который намного быстрее.Более быстрый способ - вставить отдельные строки во временную таблицу. Используя delete, мне понадобилось несколько часов, чтобы удалить дубликаты из таблицы из 8 миллионов строк. Используя вставку и отчетливый, это заняло всего 13 минут.
источник
TRUNCATE TABLE tableName
а 5-я строка должна сказатьINSERT INTO tableName SELECT * FROM tempTableName;
Решение, которое легко понять и работает без первичного ключа:
1) добавить новый логический столбец
2) добавить ограничение на дублирующиеся столбцы И новый столбец
3) установите для логического столбца значение true. Это будет успешно только на одной из дублированных строк из-за нового ограничения
4) удалить строки, которые не были помечены как tokeep
5) удалить добавленный столбец
Я предлагаю, чтобы вы сохранили ограничение, которое вы добавили, чтобы новые дубликаты были предотвращены в будущем.
источник
Удалите дублирующиеся строки с помощью инструкции DELETE JOIN MySQL предоставляет вам инструкцию DELETE JOIN, которую можно использовать для быстрого удаления дублирующихся строк.
Следующая инструкция удаляет дублирующиеся строки и сохраняет самый высокий идентификатор:
источник
Я нашел простой способ. (держать последнюю)
источник
Просто и быстро для всех случаев:
источник
Это удалит дублирующиеся строки с одинаковыми значениями для заголовка, компании и сайта. Первое вхождение будет сохранено, а все остальные дубликаты будут удалены
источник
Я продолжаю посещать эту страницу всякий раз, когда я гуглю "удаляю дубликаты из mysql", но мои решения theIGNORE не работают, потому что у меня есть таблицы InnoDB mysql
этот код работает лучше в любое время
tableToclean = имя таблицы, которую нужно очистить
tableToclean_temp = временная таблица создана и удалена
источник
Это решение переместит дубликаты в одну таблицу, а уникальные в другую .
источник
SELECT * FROM jobs GROUP BY site_id, company, title, location
?Начиная с версии 8.0 (2018), MySQL наконец поддерживает оконные функции .
Оконные функции удобны и эффективны. Вот решение, которое демонстрирует, как использовать их для решения этой задачи.
В подзапросе мы можем использовать
ROW_NUMBER()
для назначения позиции каждой записи в таблице вcolumn1/column2
группах, упорядоченных поid
. Если дубликатов нет, запись получит номер строки1
. Если дубликат существует, они будут пронумерованы по возрастаниюid
(начиная с1
).Как только записи будут правильно пронумерованы в подзапросе, внешний запрос просто удалит все записи, номер строки которых не равен 1.
Запрос:
источник
Удалить дубликат записи в таблице.
или
источник
источник
Для того, чтобы дублировать записи с уникальными столбцами, например, COL1, COL2, COL3 не должны быть реплицированы (предположим, что мы пропустили 3 уникальных столбца в структуре таблицы и несколько дублированных записей были внесены в таблицу)
Надеюсь поможет дев.
источник
TL; TR;
Очень описанный учебник для решения этой проблемы можно найти на сайте mysqltutorial.org :
Как удалить повторяющиеся строки в MySQL
Очень ясно показано, как удалять дублирующиеся строки тремя различными способами :
А) Использование
DELETE JOIN
заявленияБ) Использование промежуточной таблицы
В) Использование
ROW_NUMBER()
функцииЯ надеюсь, что это кому-то поможет.
источник
У меня есть таблица, которые забывают добавить первичный ключ в строке идентификатора. Хотя это имеет auto_increment на идентификатор. Но однажды одна вещь воспроизводит журнал базы данных mysql в базе данных, который вставляет несколько повторяющихся строк.
Я удаляю дубликат строки
select T1.* from table_name T1 inner join (select count(*) as c,id from table_name group by id) T2 on T1.id = T2.id where T2.c > 1 group by T1.id;
удалить повторяющиеся строки по идентификатору
вставить строку из экспортируемых данных.
Затем добавьте первичный ключ по id
источник
Мне нравится быть более точным в отношении того, какие записи я удаляю, поэтому вот мое решение:
источник
Вы можете легко удалить дубликаты записей из этого кода.
источник
Я должен был сделать это с текстовыми полями и натолкнулся на ограничение в 100 байтов в индексе.
Я решил эту проблему, добавив столбец, выполнив md5-хэш полей и выполнив изменение.
источник