Вопрос

Я хочу удалить дублирующиеся записи в базе данных 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

Есть какие-нибудь мысли о том, как это можно сделать?Я пытаюсь избежать выполнения первого запроса, а затем поиска дубликатов с помощью второго запроса в коде.

Это было полезно?

Решение

Ключ в том, чтобы переписать этот запрос так, чтобы его можно было использовать в качестве подзапроса.

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;

Другие советы

SELECT date FROM logs group by date having count(*) >= 2

Почему бы просто не ОБЪЕДИНИТЬ таблицу с самой собой?

SELECT a.firstname, a.lastname, a.address
FROM list a
INNER JOIN list b ON a.address = b.address
WHERE a.id <> b.id

РАЗЛИЧИЕ необходимо, если адрес может существовать более двух раз.

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

SELECT COUNT(*) c,title FROM `data` GROUP BY title HAVING c > 1;
select `cityname` from `codcities` group by `cityname` having count(*)>=2

Это аналогичный запрос, который вы запрашивали, и он на 200% рабочий и простой.Наслаждайтесь!!!

Поиск дубликатов пользователей с помощью Эл. адрес с помощью этого запроса...

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;

Разве это не проще :

SELECT *
FROM tc_tariff_groups
GROUP BY group_id
HAVING COUNT(group_id) >1

?

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

SELECT COUNT(*), column1, column2 
FROM tablename
GROUP BY column1, column2
HAVING COUNT(*)>1;

Другим решением было бы использовать псевдонимы таблиц, например:

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таблицы сохранения -- p1 и p2 -- исходя из этого, а затем выполняя объединение в столбце адреса (строка 3).4-я строка гарантирует, что одна и та же запись не будет отображаться несколько раз в вашем наборе результатов ("повторяющиеся дубликаты").

Поиск дубликатов адреса это гораздо сложнее, чем кажется, особенно если вам требуется точность.В данном случае запроса MySQL недостаточно...

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

Существует несколько сторонних сервисов, которые будут помечать дубликаты в списке для вас.Выполнение этого исключительно с помощью подзапроса MySQL не будет учитывать различия в форматах адресов и стандартах.В USPS (для адреса в США) есть определенные рекомендации по созданию этих стандартов, но только несколько поставщиков сертифицированы для выполнения таких операций.

Итак, я бы порекомендовал, чтобы лучшим ответом для вас было экспортировать таблицу, например, в CSV-файл и отправить ее в работающий обработчик списков.Одним из таких является Живой адрес который автоматически сделает это за вас от нескольких секунд до нескольких минут.Он будет помечать повторяющиеся строки новым полем с именем "Duplicate" и значением Y в нем.

Это будет не очень эффективно, но это должно сработать:

SELECT *
FROM list AS outer
WHERE (SELECT COUNT(*)
        FROM list AS inner
        WHERE inner.address = outer.address) > 1;

Это позволит выбрать дубликаты за один проход таблицы, без подзапросов.

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

Подробности смотрите в статье в моем блоге:

Это также покажет вам, сколько дубликатов имеется, и упорядочит результаты без объединений

SELECT  `Language` , id, COUNT( id ) AS how_many
FROM  `languages` 
GROUP BY  `Language` 
HAVING how_many >=2
ORDER BY how_many DESC
 SELECT firstname, lastname, address FROM list
 WHERE 
 Address in 
 (SELECT address FROM list
 GROUP BY address
 HAVING count(*) > 1)
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

Этот запрос выдаст вам все отдельные записи адресов в вашей таблице списка...Я не уверен, как это будет работать, если у вас есть какие-либо значения первичного ключа для name и т.д..

Самая быстрая процедура запросов на удаление дубликатов:

/* 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;

Лично этот запрос решил мою проблему:

SELECT `SUB_ID`, COUNT(SRV_KW_ID) as subscriptions FROM `SUB_SUBSCR` group by SUB_ID, SRV_KW_ID HAVING subscriptions > 1;

Что делает этот скрипт, так это показывает все идентификаторы подписчиков, существующие более одного раза, в таблице и количество найденных дубликатов.

Это столбцы таблицы:

| 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    |                |

Надеюсь, это будет полезно и для вас!

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

Заменить город вместе с вашим Столом.Заменить Имя с именем вашего поля

    SELECT *
    FROM (SELECT  address, COUNT(id) AS cnt
    FROM list
    GROUP BY address
    HAVING ( COUNT(id) > 1 ))

Ответ Властелина это действительно лучшее, и я бы порекомендовал еще одно изменение:используйте LIMIT, чтобы убедиться, что база данных не будет перегружена:

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, если неизвестно, ГДЕ и когда совершать объединения.Начните с небольшого значения, проверьте, насколько объемным является запрос, а затем увеличьте лимит.

    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 |
+---------------------+------------+---+

Чтобы быстро просмотреть повторяющиеся строки, вы можете запустить один простой запрос

Здесь я запрашиваю таблицу и перечисляю все повторяющиеся строки с одинаковыми user_id, market_place и артикулом:

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;

Резервное копирование, двойная проверка, верификация, проверка резервной копии, затем выполнение.

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'

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top