показать повторяющиеся записи в столбце в sql, db: mysql [duplicate]

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

581
задан Chris Bartow 12 May 2009 в 19:24
поделиться

21 ответ

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

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;
617
ответ дан ChrisP 26 August 2018 в 18:25
поделиться
  • 1
    Будьте осторожны с подзапросами. Подзапросы являются / могут быть смехотворно плохими для проблем производительности. Если это часто случается и / или с множеством повторяющихся записей, я бы подумал о переносе обработки из базы данных и в наборе данных. – bdwakefield 12 May 2009 в 20:18
  • 2
    Это некоррелированный подзапрос, поэтому не должно быть слишком плохо, если только сам запрос не плохо разработан. – ʞɔıu 12 May 2009 в 20:36
  • 3
    @nick: Это по-прежнему актуальная точка в целом о подзапросах. – Powerlord 12 May 2009 в 22:37
  • 4
    Это правильная идея, но опять же, как показано ниже, это работает только в том случае, если адреса гарантированно стандартизируются ... – Matt 28 September 2012 в 22:46
  • 5
    +1 с этим запросом вы можете найти дубликаты, но также три раза, четверостишие ..... и так далее – albanx 22 October 2012 в 13:31

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»

-1
ответ дан aad 26 August 2018 в 18:25
поделиться
8
ответ дан Chad Birch 26 August 2018 в 18:25
поделиться

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

0
ответ дан Community 26 August 2018 в 18:25
поделиться
select `cityname` from `codcities` group by `cityname` having count(*)>=2

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

40
ответ дан dakshbhatt21 26 August 2018 в 18:25
поделиться
SELECT date FROM logs group by date having count(*) >= 2
306
ответ дан DaveShaw 26 August 2018 в 18:25
поделиться
  • 1
    Это был самый простой рабочий запрос для использования с Laravel. Просто пришлось добавить ->having(DB::raw('count(*)'), '>', 2) к запросу. Большое спасибо! – Kovah 7 December 2015 в 15:28
  • 2
    Хорошо работает с таблицей из 10 миллионов строк. Это должен быть лучший ответ – Terry Lin 12 December 2015 в 07:30
  • 3
    Будьте осторожны с этим ответом. Он возвращает только один из дубликатов. Если у вас более двух копий одной записи, вы не увидите их всех, и после удаления возвращенной записи все равно будут дубликаты в вашей таблице. – Mikiko Jane 24 April 2016 в 20:35
  • 4
    Почему >=2? Просто используйте HAVING COUNT(*) > 1 – BadHorsie 16 May 2016 в 15:28
  • 5
    Классно, чувак..... – Faris Rayhan 31 October 2017 в 07:32

Найти дубликатов пользователей по электронному адресу с этим запросом ...

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;
34
ответ дан doublejosh 26 August 2018 в 18:25
поделиться
  • 1
    Чтобы найти фактический дубликат, вам нужен только внутренний запрос. Это намного быстрее, чем другие ответы. – antonagestam 8 May 2014 в 21:52

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

SELECT COUNT(*) c,title FROM `data` GROUP BY title HAVING c > 1;
49
ответ дан Erick Martim 26 August 2018 в 18:25
поделиться

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

SELECT COUNT(*), column1, column2 
FROM tablename
GROUP BY column1, column2
HAVING COUNT(*)>1;
18
ответ дан George Garchagudashvili 26 August 2018 в 18:25
поделиться
    SELECT *
    FROM (SELECT  address, COUNT(id) AS cnt
    FROM list
    GROUP BY address
    HAVING ( COUNT(id) > 1 ))
4
ответ дан Ghostman 26 August 2018 в 18:25
поделиться
  • 1
    Пробовал и это, но, похоже, просто зависает. Верьте, что возврат из внутреннего запроса не удовлетворяет формату параметров IN. – doublejosh 26 January 2012 в 02:35
  • 2
    Что вы имеете в виду, не удовлетворяет формату параметров? Все потребности IN в том, что ваш подзапрос должен возвращать один столбец. Это очень просто. Скорее всего, ваш подзапрос генерируется в столбце, который не индексируется, поэтому он занимает слишком много времени для запуска. Я бы предложил, если потребуется много времени, чтобы разбить его на два вопроса. Возьмите подзапрос, запустите его сначала во временную таблицу, создайте на ней индекс, затем запустите полный запрос, выполнив подзапрос, где ваше дублирующее поле во временной таблице. – Ryan Roper 26 January 2012 в 20:29
  • 3
    Я беспокоился, что IN требовал список с разделителями-запятыми, а не столбец, что было просто неправильно. Вот запрос, который работал для меня: 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 ) dup ON users.mail = dup.mail ORDER BY users.mail, users.created; – doublejosh 1 February 2012 в 20:34

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

SELECT p1.id, p2.id, p1.address
FROM list AS p1, list AS p2
WHERE p1.address = p2.address
AND p1.id != p2.id

Все, что вы действительно делаете в этом случае, - это взять исходную таблицу list , создав два выдать таблицы - p1 и p2 - из этого, а затем выполнить соединение в столбце адреса (строка 3). 4-я строка гарантирует, что одна и та же запись не будет отображаться несколько раз в вашем наборе результатов («дублировать дубликаты»).

12
ответ дан jerdiggity 26 August 2018 в 18:25
поделиться
  • 1
    Работает хорошо. Если WHERE проверяет с помощью LIKE, то также обнаруживаются апострофы. Делает запрос медленнее, но в моем случае это один таймер. – gossi 17 June 2012 в 14:52
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

Замените город таблицей. Замените имя именем вашего поля

3
ответ дан Lalit Patel 26 August 2018 в 18:25
поделиться
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

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

4
ответ дан mabarroso 26 August 2018 в 18:25
поделиться

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

SELECT  `Language` , id, COUNT( id ) AS how_many
FROM  `languages` 
GROUP BY  `Language` 
HAVING how_many >=2
ORDER BY how_many DESC
7
ответ дан Martin Tonev 26 August 2018 в 18:25
поделиться
  • 1
    отлично, потому что он все еще говорит, сколько записей дублируется – denis 22 February 2018 в 14:33
  • 2
    Именно это и есть моя точка зрения. – Martin Tonev 22 February 2018 в 15:35

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

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

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

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

11
ответ дан Matt 26 August 2018 в 18:25
поделиться
  • 1
    +1 для просмотра сложности, связанной с сопоставлением строк адреса, хотя вы можете указать, что «дублированные записи» OP, вопрос не является сложным сам по себе, но при сравнении адресов – story 6 February 2012 в 22:39

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

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

См. статью в моем блоге для деталей:

10
ответ дан Quassnoi 26 August 2018 в 18:25
поделиться
  • 1
    Не для nitpick, но FROM (SELECT ...) aoo является подзапросом: -P – Rocket Hazmat 27 April 2012 в 20:07

Почему не просто 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, если адрес может существовать более двух раз.

190
ответ дан rudolfson 26 August 2018 в 18:25
поделиться
  • 1
    Я тоже тестировал это, и это было почти в 6 раз медленнее по сравнению с принятым решением в моей ситуации (последний MySQL, таблица из 120 000 строк). Возможно, из-за этого требуется временная таблица, запустите EXPLAIN на обоих, чтобы увидеть различия. – user 5 January 2012 в 18:06
  • 2
    Я изменил последнюю часть запроса на WHERE a.id > b.id, чтобы отфильтровать только новые дубликаты, таким образом, я могу сделать DELETE непосредственно на результат. Переключите сравнение, чтобы просмотреть старые дубликаты. – Stoffe 11 September 2013 в 08:30
  • 3
    Это заняло 50 секунд, чтобы побежать, ответ @ doublejosh занял 0,13 секунды. – antonagestam 8 May 2014 в 21:53
  • 4
    Я должен добавить, что этот ответ дает повторяющиеся ответы, несмотря на WHERE, как в случае, если один адрес утроился, выходные строки удваиваются. Если он вчетверо, я считаю, что ответ будет утроен. – Wli 15 July 2016 в 12:54
  • 5
    Я проверил это в leetcode " leetcode.com/problems/duplicate-emails/" ;. Это было быстрее по сравнению с подзапросом. – billow 27 October 2016 в 15:42

Процедура быстрого удаления дубликатов:

/* 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;
4
ответ дан Sam 26 August 2018 в 18:25
поделиться
  • 1
    Это, очевидно, удаляет только первую запись из каждой группы дубликатов. – Palec 15 February 2015 в 13:08

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

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

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

4
ответ дан slm 26 August 2018 в 18:25
поделиться

Разве это не так:

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

?

7
ответ дан Tudor 26 August 2018 в 18:25
поделиться
  • 1
    работал для меня, где мне приходилось обрабатывать ~ 10 000 повторяющихся строк, чтобы сделать их уникальными, намного быстрее, чем загружать все 600 000 строк. – adrianTNT 15 April 2018 в 17:04
  • 2
    намного проще – Shwet 17 May 2018 в 06:36
    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 |
+---------------------+------------+---+
0
ответ дан Usman Yaqoob 26 August 2018 в 18:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: