Найти дубликаты записей в MySQL
Я хочу вытащить дубликаты записей в базе данных MySQL. Это можно сделать с помощью:
SELECT address, count(id) as cnt FROM list
GROUP BY address HAVING cnt > 1
Результат:
100 MAIN ST 2
Я хотел бы потянуть его так, чтобы он показывал каждую строку, которая является дубликатом. Что-то вроде:
JIM JONES 100 MAIN ST
JOHN SMITH 100 MAIN ST
Любые мысли о том, как это можно сделать? Я пытаюсь не делать первый, а затем искать дубликаты со вторым запросом в коде.
Ответы
Ответ 1
Ключ должен переписать этот запрос так, чтобы он мог использоваться как подзапрос.
SELECT firstname,
lastname,
list.address
FROM list
INNER JOIN (SELECT address
FROM list
GROUP BY address
HAVING COUNT(id) > 1) dup
ON list.address = dup.address;
Ответ 2
SELECT date FROM logs group by date having count(*) >= 2
Ответ 3
Почему не просто INNER ПРИСОЕДИНИТЬСЯ к таблице с собой?
SELECT a.firstname, a.lastname, a.address
FROM list a
INNER JOIN list b ON a.address = b.address
WHERE a.id <> b.id
Требуется DISTINCT, если адрес может существовать более двух раз.
Ответ 4
Я попробовал лучший ответ, выбранный для этого вопроса, но это несколько смутило меня. Мне на самом деле нужно было только на одном поле из моего стола. Следующий пример из этой ссылки очень хорошо работал у меня:
SELECT COUNT(*) c,title FROM `data` GROUP BY title HAVING c > 1;
Ответ 5
select `cityname` from `codcities` group by `cityname` having count(*)>=2
Это тот же запрос, который вы запросили, и его 200% -ная работа и легко.
Наслаждайтесь!!!
Ответ 6
Найти дубликатов пользователей по адресу электронной почты с помощью этого запроса...
SELECT users.name, users.uid, users.mail, from_unixtime(created)
FROM users
INNER JOIN (
SELECT mail
FROM users
GROUP BY mail
HAVING count(mail) > 1
) dupes ON users.mail = dupes.mail
ORDER BY users.mail;
Ответ 7
Разве это не проще?
SELECT *
FROM tc_tariff_groups
GROUP BY group_id
HAVING COUNT(group_id) >1
?
Ответ 8
мы можем найти, что дубликаты зависят от более чем одного поля. В этих случаях вы можете использовать формат ниже.
SELECT COUNT(*), column1, column2
FROM tablename
GROUP BY column1, column2
HAVING COUNT(*)>1;
Ответ 9
Другим решением будет использование псевдонимов таблицы, например:
SELECT p1.id, p2.id, p1.address
FROM list AS p1, list AS p2
WHERE p1.address = p2.address
AND p1.id != p2.id
Все, что вы действительно делаете в этом случае, - это взять исходную таблицу списков, создав две таблицы p - p 1 и p 2 - из этого, а затем выполните соединение в столбце адреса (строка 3). 4-я строка гарантирует, что одна и та же запись не будет отображаться несколько раз в вашем наборе результатов ( "дублировать дубликаты" ).
Ответ 10
Поиск дублирующих адресов намного сложнее, чем кажется, особенно если вам нужна точность. В этом случае запроса MySQL недостаточно...
Я работаю в SmartyStreets, где мы обращаемся к валидации и дедупликации и другим материалам, и я видел множество разнообразных проблем с подобными проблемами.
Существует несколько сторонних служб, которые будут отмечать дубликаты в списке для вас. Выполнение этого только с подзапросом MySQL не будет учитывать различия в форматах и стандартах адресов. У USPS (для адреса США) есть определенные рекомендации по составлению этих стандартов, но только несколько поставщиков сертифицированы для выполнения таких операций.
Итак, я бы рекомендовал, что лучшим ответом для вас является экспорт таблицы в CSV файл, например, и отправку его в удобный процессор списка. Одним из таких является LiveAddress, который будет выполнен для вас за несколько секунд до нескольких минут автоматически. Он будет отмечать повторяющиеся строки с новым полем "Дубликат" и значением Y
в нем.
Ответ 11
Не будет очень эффективным, но он должен работать:
SELECT *
FROM list AS outer
WHERE (SELECT COUNT(*)
FROM list AS inner
WHERE inner.address = outer.address) > 1;
Ответ 12
Это позволит выбрать дубликаты в одном проходе таблицы, без подзапросов.
SELECT *
FROM (
SELECT ao.*, (@r := @r + 1) AS rn
FROM (
SELECT @_address := 'N'
) vars,
(
SELECT *
FROM
list a
ORDER BY
address, id
) ao
WHERE CASE WHEN @_address <> address THEN @r := 0 ELSE 0 END IS NOT NULL
AND (@_address := address ) IS NOT NULL
) aoo
WHERE rn > 1
Этот запрос актуализирует ROW_NUMBER()
, присутствующий в Oracle
и SQL Server
Подробнее см. статью в моем блоге:
Ответ 13
Это также покажет вам, сколько дубликатов имеет и будет заказывать результаты без объединений
SELECT `Language` , id, COUNT( id ) AS how_many
FROM `languages`
GROUP BY `Language`
HAVING how_many >=2
ORDER BY how_many DESC
Ответ 14
SELECT firstname, lastname, address FROM list
WHERE
Address in
(SELECT address FROM list
GROUP BY address
HAVING count(*) > 1)
Ответ 15
select * from table_name t1 inner join (select distinct <attribute list> from table_name as temp)t2 where t1.attribute_name = t2.attribute_name
Для вашей таблицы это будет что-то вроде
select * from list l1 inner join (select distinct address from list as list2)l2 where l1.address=l2.address
Этот запрос предоставит вам все отдельные записи в таблице списка... Я не уверен, как это будет работать, если у вас есть значения первичного ключа для имени и т.д.
Ответ 16
Самая быстрая процедура удаления запросов дубликатов:
/* create temp table with one primary column id */
INSERT INTO temp(id) SELECT MIN(id) FROM list GROUP BY (isbn) HAVING COUNT(*)>1;
DELETE FROM list WHERE id IN (SELECT id FROM temp);
DELETE FROM temp;
Ответ 17
Лично этот запрос решил мою проблему:
SELECT `SUB_ID`, COUNT(SRV_KW_ID) as subscriptions FROM `SUB_SUBSCR` group by SUB_ID, SRV_KW_ID HAVING subscriptions > 1;
Что это за script показывает все идентификатор подписчика, который существует более одного раза в таблице, и количество найденных дубликатов.
Это столбцы таблицы:
| SUB_SUBSCR_ID | int(11) | NO | PRI | NULL | auto_increment |
| MSI_ALIAS | varchar(64) | YES | UNI | NULL | |
| SUB_ID | int(11) | NO | MUL | NULL | |
| SRV_KW_ID | int(11) | NO | MUL | NULL | |
Надеюсь, это будет полезно и вам!
Ответ 18
SELECT t.*,(select count(*) from city as tt where tt.name=t.name) as count FROM `city` as t where (select count(*) from city as tt where tt.name=t.name) > 1 order by count desc
Замените город на таблицу.
Замените имя на имя своего поля
Ответ 19
SELECT *
FROM (SELECT address, COUNT(id) AS cnt
FROM list
GROUP BY address
HAVING ( COUNT(id) > 1 ))
Ответ 20
Ответ Powerlord действительно лучший, и я бы порекомендовал еще одно изменение: используйте LIMIT, чтобы убедиться, что db не будет перегружен:
SELECT firstname, lastname, list.address FROM list
INNER JOIN (SELECT address FROM list
GROUP BY address HAVING count(id) > 1) dup ON list.address = dup.address
LIMIT 10
Хорошая привычка использовать LIMIT, если нет ГДЕ и при создании объединений. Начните с малого значения, проверьте, насколько тяжелен запрос, а затем увеличьте предел.
Ответ 21
Find duplicate Records:
Suppose we have table : Student
student_id int
student_name varchar
Records:
+------------+---------------------+
| student_id | student_name |
+------------+---------------------+
| 101 | usman |
| 101 | usman |
| 101 | usman |
| 102 | usmanyaqoob |
| 103 | muhammadusmanyaqoob |
| 103 | muhammadusmanyaqoob |
+------------+---------------------+
Now we want to see duplicate records
Use this query:
select student_name,student_id ,count(*) c from student group by student_id,student_name having c>1;
+--------------------+------------+---+
| student_name | student_id | c |
+---------------------+------------+---+
| usman | 101 | 3 |
| muhammadusmanyaqoob | 103 | 2 |
+---------------------+------------+---+
Ответ 22
Чтобы быстро увидеть повторяющиеся строки, вы можете выполнить один простой запрос
Здесь я опрашиваю таблицу и перечисляю все повторяющиеся строки с одинаковыми user_id, market_place и sku:
select user_id, market_place,sku, count(id)as totals from sku_analytics group by user_id, market_place,sku having count(id)>1;
Чтобы удалить дублирующуюся строку, вы должны решить, какую строку вы хотите удалить. Например, с более низким идентификатором (обычно старше) или, возможно, с другой информацией о дате. В моем случае я просто хочу удалить нижний идентификатор, поскольку более новый идентификатор является самой последней информацией.
Сначала проверьте, удаляются ли нужные записи. Здесь я выбираю запись среди дубликатов, которые будут удалены (по уникальному идентификатору).
select a.user_id, a.market_place,a.sku from sku_analytics a inner join sku_analytics b where a.id< b.id and a.user_id= b.user_id and a.market_place= b.market_place and a.sku = b.sku;
Затем я запускаю запрос на удаление, чтобы удалить обманщиков:
delete a from sku_analytics a inner join sku_analytics b where a.id< b.id and a.user_id= b.user_id and a.market_place= b.market_place and a.sku = b.sku;
Резервное копирование, двойная проверка, проверка, проверка резервной копии и выполнение.
Ответ 23
select address from list where address = any (select address from (select address, count(id) cnt from list group by address having cnt > 1 ) as t1) order by address
внутренний подзапрос возвращает строки с повторяющимся адресом, тогда
внешний подзапрос возвращает столбец адресов для адреса с дубликатами.
внешний подзапрос должен возвращать только один столбец, потому что он используется как операнд для оператора "= any"