2010-09-08 4 views
13

У меня есть таблица данных, и есть много повторяющихся записей от представлений пользователей.Удалить дублирующиеся строки, оставив самую старую строку Только?

Я хочу удалить все дубликаты строк на основе поля subscriberEmail, оставив только оригинальное представление.

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

Как это сделать без обмена таблицами?
Моя таблица содержит уникальные идентификаторы для каждой строки.

+0

Вы должны отметьте ответ как «принятый» :-) – watery

ответ

27

Поскольку вы используете столбец ID в качестве индикатора которого запись является «оригинальным»:

delete x 
from myTable x 
join myTable z on x.subscriberEmail = z.subscriberEmail 
where x.id > z.id 

Это оставит одну запись на адрес электронной почты.

редактировать добавить:

Для объяснения выше запрос ...

Идея заключается в том, чтобы присоединиться к таблице против себя. Представьте, что у вас есть две копии таблицы, каждая из которых называется чем-то другим. Затем вы можете сравнить их друг с другом и найти самый низкий идентификатор или для каждого адреса электронной почты. Затем вы увидите дубликаты записей, которые были созданы позже, и могут удалить их. (Я визуализировал Excel, думая об этом.)

Чтобы сделать эту операцию на столе, сравните ее с собой и сможете идентифицировать каждую сторону, вы используете псевдонимы таблиц. x - псевдоним таблицы. Он присваивается в предложении from следующим образом: from <table> <alias>. x теперь можно использовать в другом месте в том же запросе, чтобы ссылаться на эту таблицу как ярлык.

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

Псевдонимы используются для обозначения обоих «экземпляров» таблицы. from myTable x join myTable z on x.subscriberEmail = z.subscriberEmail ударяет по столу против себя, где совпадают письма. Без предложения where, которое следует, каждая запись будет выбрана, поскольку она может быть объединена против самого себя.

Статья where ограничивает выбранные записи. where x.id > z.id позволяет «экземпляру» aliased x содержать только записи, соответствующие сообщениям электронной почты, но имеющие более высокое значение id. Данные, которые вы действительно хотите в таблице, уникальные адреса электронной почты (с наименьшим идентификатором) не будут частью x и не будут удалены. Единственными записями в x будут дублированные записи (адреса электронной почты), которые имеют более высокий id, чем оригинальная запись для этого адреса электронной почты.

Джойн и где пункты могут быть объединены в этом случае:

delete x 
    from myTable x 
    join myTable z 
    on x.subscriberEmail = z.subscriberEmail 
     and x.id > z.id 

Для предотвращения дублирования, рассмотреть вопрос о внесении в столбце subscriberEmail УНИКАЛЬНЫЙ индексированный столбец.

+0

Эй, я не понимаю, что такое X, и где вводится дата. Я мог бы использовать идентификатор, так как для каждого или для даты есть первичный идентификатор. ID звучит проще –

+0

Эй, это сработало !!! Я изменил «createdOn» на «id» и presto! хаха спасибо - Heres код, который я использовал в PHP: mysql_query ("удалить х из my_table х присоединиться к my_table г на x.subscriberEmail = z.subscriberEmail где x.id> z.id") или умереть (mysql_error ()); –

+0

Можете ли вы объяснить, как читать этот код на английском языке? Это помогает уметь логически читать что-то, чтобы понять синтаксис. Также, как я могу предотвратить дубликаты в первую очередь? Я уже использую Insert IGNORE, но он не игнорирует –

0

Если у вас есть уникальный идентификатор для каждой строки, вы можете попробовать что-то вроде этого. Не спрашивайте меня, почему именно вам нужен второй оператор select, mysql не позволит мне выполнить иначе. Кроме того, группа по любым столбцам делает ваши результаты уникальными.

delete from my_table where id in (
    select id from (
    select id from my_table a group by subscriberEmail having count(*) > 1 
) b 
); 
+1

Я считаю, что это удалит все из них, а не только дополнительные. – Fosco

+0

Нет, это не так. Группа будет группироваться как строки по подписчику. Таким образом, будет выбран абонент с более чем 1 электронным адресом (со счетом (*)> 1). На данный момент у вас в значительной степени есть отчетный набор подписчиков с более чем 1 электронной почтой. Возьмите идентификатор из этого набора записей и удалите его. Я попробовал, и это работает как шарм. –

+0

Запуск этого кода вызывает ошибку «# 1064 - У вас есть ошибка в синтаксисе SQL, проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с« 'в строке 2 »- Код ниже –

1

Как об этом, теперь вы не должны создавать временные таблицы, используя сам присоединяется

DELETE u1 FROM users u1, users u2 WHERE u1.id < u2.id AND u1.email = u2.email 

Чтобы проверить, есть ли какие-либо повторяющиеся записи в таблице

SELECT count(*) as Count, email FROM users u group by email having Count > 1 
Смежные вопросы