Выберите все записи с дублирующимся значением [duplicate]

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

SqlConnection connection = null;
connection.Open();

Это вызовет ошибку, потому что, пока я объявил переменную «connection», она не указала ни на что. Когда я пытаюсь вызвать член «Open», для его устранения нет ссылки, и он будет вызывать ошибку.

Чтобы избежать этой ошибки:

  1. Всегда инициализируйте свои объекты, прежде чем пытаться что-либо с ними делать.
  2. Если вы не уверены, что объект имеет значение null, проверьте его с помощью object == null.

Инструмент Resharper JetBrains определит каждое место в вашем коде, которое имеет возможность ошибки нулевой ссылки, позволяя вам ввести нулевую проверку. Эта ошибка является источником ошибок номер один, IMHO.

610
задан Jon Tackabury 27 March 2009 в 05:22
поделиться

20 ответов

Сделайте SELECT с предложением GROUP BY. Скажем, name - это столбец, в котором вы хотите найти дубликаты:

SELECT name, COUNT(*) c FROM table GROUP BY name HAVING c > 1;

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

1200
ответ дан the Tin Man 26 August 2018 в 05:47
поделиться
  • 1
    Но как это полезно, если вы не можете получить идентификаторы строк с повторяющимися значениями? Да, вы можете выполнить новое сопоставление запросов для каждого повторяющегося значения, но можно ли просто перечислить дубликаты? – NobleUplift 24 July 2014 в 15:41
  • 2
    @NobleUplift Вы можете сделать GROUP_CONCAT(id), и он отобразит идентификаторы. См. Мой ответ для примера. – Matt Rardon 19 February 2015 в 01:53
  • 3
    Что бы это значило, если бы он сказал ERROR: column "c" does not exist LINE 1? – User 4 October 2015 в 17:36
  • 4
    Я смущен, почему это принятый ответ и почему у него так много оборотов. ОП спросил: «Я бы хотел найти все записи, которые имеют повторяющиеся значения в этом столбце». Этот ответ возвращает таблицу подсчетов. -1 – Monica Heddneck 3 April 2017 в 20:56
  • 5
    Для тех, кто не понимает, как работает HAVING - это просто фильтр в результирующем наборе, поэтому это происходит после основного запроса. – John Hunt 22 June 2017 в 10:02

Взяв @ maxyfc ответ , мне нужно было найти все строк, которые были возвращены с повторяющимися значениями, поэтому я мог бы их редактировать в MySQL Workbench :

SELECT * FROM table
   WHERE field IN (
     SELECT field FROM table GROUP BY field HAVING count(*) > 1
   ) ORDER BY field
6
ответ дан AbsoluteƵERØ 26 August 2018 в 05:47
поделиться
  • 1
    Большое вам спасибо, это лучший SQL для моей потребности – softcod.com 31 July 2017 в 14:33

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

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

SELECT t1.* FROM table as t1 LEFT JOIN table as t2 ON t1.name=t2.name and t1.id!=t2.id WHERE t2.id IS NOT NULL ORDER BY t1.name
3
ответ дан Adam Fischer 26 August 2018 в 05:47
поделиться

Один очень поздний вклад ... в случае, если он помогает любому waaaaaay вниз по линии ... У меня была задача найти соответствующие пары транзакций (на самом деле обе стороны передачи от учетной записи к учетной записи) в банковском приложении, чтобы определите, какие из них были «from» и «to» для каждой транзакции между транзакциями, поэтому мы закончили с этим:

SELECT 
    LEAST(primaryid, secondaryid) AS transactionid1,
    GREATEST(primaryid, secondaryid) AS transactionid2
FROM (
    SELECT table1.transactionid AS primaryid, 
        table2.transactionid AS secondaryid
    FROM financial_transactions table1
    INNER JOIN financial_transactions table2 
    ON table1.accountid = table2.accountid
    AND table1.transactionid <> table2.transactionid 
    AND table1.transactiondate = table2.transactiondate
    AND table1.sourceref = table2.destinationref
    AND table1.amount = (0 - table2.amount)
) AS DuplicateResultsTable
GROUP BY transactionid1
ORDER BY transactionid1;

. Результатом является то, что DuplicateResultsTable предоставляет строки, содержащие совпадение (т. е. дублировать), но он также предоставляет идентичный идентификатор транзакции в обратном порядке во второй раз, когда он совпадает с одной и той же парой, поэтому внешний SELECT должен группироваться по первому идентификатору транзакции, который выполняется с помощью LEAST и GREATEST, чтобы убедиться, что два транзакционных файла всегда находятся в одном порядке в результатах, что делает его безопасным для GROUP первым, что устраняет все повторяющиеся совпадения. Прошел почти миллион записей и определил 12 000+ матчей всего за 2 секунды. Конечно, transactionid - это основной индекс, который действительно помог.

1
ответ дан Andrew LaPrise 26 August 2018 в 05:47
поделиться
SELECT ColumnA, COUNT( * )
FROM Table
GROUP BY ColumnA
HAVING COUNT( * ) > 1
0
ответ дан AsgarAli Khanusiya 26 August 2018 в 05:47
поделиться
  • 1
    Это неверно, поскольку оно также находит уникальные вхождения. 0 должно быть 1. – Kafoso 6 January 2017 в 15:45

Ниже вы найдете все product_id, которые используются более одного раза. Вы получаете только одну запись для каждого product_id.

SELECT product_id FROM oc_product_reward GROUP BY product_id HAVING count( product_id ) >1

Код, взятый из: http://chandreshrana.blogspot.in/2014/12/find-duplicate-records-based-on -any.html

3
ответ дан Chandresh 26 August 2018 в 05:47
поделиться

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

Но если вам нужно проверить с большим количеством столбцов и хотите проверить комбинацию результата, чтобы этот запрос работал нормально:

SELECT COUNT(CONCAT(name,email)) AS tot,
       name,
       email
FROM users
GROUP BY CONCAT(name,email)
HAVING tot>1 (This query will SHOW the USER list which ARE greater THAN 1
              AND also COUNT)
8
ответ дан davejal 26 August 2018 в 05:47
поделиться
  • 1
    Действительно ли это добавляет больше значения, чем принятый ответ 500ish x upvoted? – LDMJoe 24 November 2015 в 13:50
  • 2
    Это то, что я нашел :) ты спас свой день. – Vipul Hadiya 1 August 2016 в 13:15
SELECT * 
FROM `dps` 
WHERE pid IN (SELECT pid FROM `dps` GROUP BY pid HAVING COUNT(pid)>1)
10
ответ дан demongolem 26 August 2018 в 05:47
поделиться
  • 1
    Определенно должен быть принятый ответ – FliiFe 19 November 2016 в 19:00
  • 2
    Нет, потому что это, возможно, самый медленный из всех. Subselects, как известно, медленны, поскольку они выполняются для каждой возвращаемой строки. – Oddman 21 November 2016 в 07:33
SELECT DISTINCT a.email FROM `users` a LEFT JOIN `users` b ON a.email = b.email WHERE a.id != b.id;
2
ответ дан Hassaan 26 August 2018 в 05:47
поделиться
  • 1
    Стоит отметить, что это невыносимо медленно или может даже не закончиться, если запрашиваемый столбец не индексируется. В противном случае мне удалось изменить a.email на a.* и получить все идентификаторы строк с дубликатами. – NobleUplift 24 July 2014 в 15:53
  • 2
    @NobleUplift О чем ты говоришь? – Michael 25 October 2017 в 18:43
  • 3
    @Michael Ну, так как мне три года, я не могу тестировать любую версию MySQL, которую я использовал, но я пробовал этот же запрос в базе данных, где у столбца, который я выбрал, не было индекса на нем, поэтому потребовалось довольно осталось несколько секунд. Изменение его до SELECT DISTINCT a.* разрешилось почти мгновенно. – NobleUplift 26 October 2017 в 19:54
  • 4
    @NobleUplift Ах нормально. Я могу понять, что это медленный ... часть, которую меня беспокоит, «может даже не закончиться». – Michael 27 October 2017 в 18:58
  • 5
    @Michael. Я не помню, в какой таблице в нашей системе мне приходилось запускать этот запрос, но для тех, у кого было несколько миллионов записей, они, вероятно, закончили бы, но в то время, которое прошло так долго, что я отказался от наблюдения, когда это на самом деле закончится. – NobleUplift 27 October 2017 в 20:19

Для удаления повторяющихся строк с несколькими полями сначала привяжите их к новому уникальному ключу, который указан только для отдельных строк, а затем используйте команду «group by» для удаления повторяющихся строк с помощью того же нового уникального ключа:

Create TEMPORARY table tmp select concat(f1,f2) as cfs,t1.* from mytable as t1;
Create index x_tmp_cfs on tmp(cfs);
Create table unduptable select f1,f2,... from tmp group by cfs;
1
ответ дан irshst 26 August 2018 в 05:47
поделиться
  • 1
    можете ли вы также добавить объяснение? – Robert 4 February 2016 в 11:17
  • 2
    Почему бы не использовать CREATE TEMPORARY TABLE ...? Небольшое объяснение вашего решения было бы замечательным. – maxhb 4 February 2016 в 11:24

Мой последний запрос включил несколько ответов здесь, которые помогли - объединить группу по, count & amp; GROUP_CONCAT.

SELECT GROUP_CONCAT(id), `magento_simple`, COUNT(*) c 
FROM product_variant 
GROUP BY `magento_simple` HAVING c > 1;

Это обеспечивает идентификатор обоих примеров (разделенных запятыми), нужного мне штрих-кода и количества дубликатов.

Соответственно изменить таблицу и столбцы.

5
ответ дан Jonathan 26 August 2018 в 05:47
поделиться
CREATE TABLE tbl_master
    (`id` int, `email` varchar(15));

INSERT INTO tbl_master
    (`id`, `email`) VALUES
    (1, 'test1@gmail.com'),
    (2, 'test2@gmail.com'),
    (3, 'test1@gmail.com'),
    (4, 'test2@gmail.com'),
    (5, 'test5@gmail.com');

QUERY : SELECT id, email FROM tbl_master
WHERE email IN (SELECT email FROM tbl_master GROUP BY email HAVING COUNT(id) > 1)
2
ответ дан kodabear 26 August 2018 в 05:47
поделиться

Я предпочитаю использовать оконные функции (MySQL 8.0+), чтобы найти дубликаты, потому что я мог видеть целую строку:

WITH cte AS (
  SELECT *
    ,COUNT(*) OVER(PARTITION BY col_name) AS num_of_duplicates_group
    ,ROW_NUMBER() OVER(PARTITION BY col_name ORDER BY col_name2) AS pos_in_group
  FROM table
)
SELECT *
FROM cte
WHERE num_of_duplicates_group > 1;

DB Fiddle Demo

0
ответ дан Lukasz Szozda 26 August 2018 в 05:47
поделиться

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

SELECT GROUP_CONCAT(id), name, COUNT(*) c FROM documents GROUP BY name HAVING c > 1;
103
ответ дан Matt Rardon 26 August 2018 в 05:47
поделиться
  • 1
    Все это время, не зная о GROUP_CONCAT ()! очень полезно. – aesede 21 May 2015 в 14:36
  • 2
    Действительно оценил Мэтта. Это действительно полезно! Для тех, кто пытается обновить phpmyadmin, если вы оставите идентификатор вместе с такой функцией: SELECT id, GROUP_CONCAT(id), name, COUNT(*) c [...], он включит встроенное редактирование, и он должен обновить все вовлеченные строки (или, по крайней мере, первый из них соответствует), но, к сожалению, редактирование генерирует Ошибка Javascript ... – Armfoot 14 September 2015 в 11:25
  • 3
    Как я не могу сгруппировать все идентификаторы, но вместо этого они перечислены с первого по последний раз; со всеми их значениями в столбцах рядом с ними? Поэтому вместо группировки он просто показывает ID 1 и его значение, ID 2 и его значение. ДАЖЕ, если значения для идентификатора совпадают. – MailBlade 15 February 2018 в 10:29
  • 4
    Чрезвычайно полезный ответ, это должно быть так, чтобы все люди его видели. Я помню, как много боли я начал создавать такие списки, и он был доступен все время в качестве команды. – John 23 May 2018 в 15:45
  • 5
    – Joel Hernandez 10 August 2018 в 19:50
SELECT varchar_col
FROM table
GROUP BY varchar_col
HAVING count(*) > 1;
174
ответ дан maxyfc 26 August 2018 в 05:47
поделиться
  • 1
    Превосходный ответ @ levik, поскольку он не добавляет лишнюю колонку. Делает его полезным для использования с IN() / NOT IN(). – wmassingham 24 November 2015 в 21:42
  • 2
    Поиск дубликатов записей в нескольких столбцах в MySQL activelab.io/code-snippets/… Я нашел этот сайт полезным .. – Anurag_BEHS 14 February 2018 в 19:41
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
ответ дан Moseleyi 26 August 2018 в 05:47
поделиться
  • 1
    Выполнение того же подзапроса дважды кажется неэффективным. – NobleUplift 24 July 2014 в 15:44
  • 2
    Большое вам спасибо, это лучший SQL для моей потребности – softcod.com 31 July 2017 в 14:34
  • 3
    я удивлен, что это действительно работает для моей потребности – Baim Wrong 16 August 2018 в 04:55
SELECT DISTINCT name, count(name) as times FROM yourtable GROUP BY name
-2
ответ дан Mustafa 26 August 2018 в 05:47
поделиться
  • 1
    Имя GROUP BY с именем DISTINCT? – Saurabh Chandra Patel 23 November 2016 в 18:15
  • 2
    Да, @SaurabhChandraPatel, тот делает трюк. Ты пробовал? Я только что проверил свой ответ с 2012 года, он работает. Просто FYI. – Mustafa 29 November 2016 в 06:58
  • 3
    Показывает некоторые уникальные записи, а также дубликаты. Потребности HAVING times > 1 Далее, этот ответ не имеет объяснения. – Chris K 24 January 2018 в 16:56
SELECT  *
FROM    mytable mto
WHERE   EXISTS
        (
        SELECT  1
        FROM    mytable mti
        WHERE   mti.varchar_column = mto.varchar_column
        LIMIT 1, 1
        )

Этот запрос возвращает полные записи, а не только отдельные varchar_column.

Этот запрос не использует COUNT(*). Если имеется много дубликатов, COUNT(*) стоит дорого, и вам не нужно целое COUNT(*), вам просто нужно знать, есть ли две строки с одинаковым значением.

Имея индекс на varchar_column, конечно, значительно ускорит этот запрос.

134
ответ дан Quassnoi 26 August 2018 в 05:47
поделиться
  • 1
    Отлично! Это то, что мне нужно – Maximus 6 May 2013 в 19:10
  • 2
    Отлично. Я добавил ORDER BY varchar_column DESC в конец запроса. – trante 28 May 2014 в 21:25
  • 3
    This query returns complete records, not just distinct varchar_column's. ---- СОВЕРШЕННО. Thankuuu ..! 1 вверх. – Parag Tyagi -morpheus- 20 August 2014 в 17:52
  • 4
    Это должен быть принятый ответ, так как GROUP BY и HAVING возвращает только один из возможных дубликатов. Кроме того, производительность с индексированным полем вместо COUNT(*) и возможность ORDER BY группировать дубликаты записей. – Rémi Breton 22 September 2015 в 20:08
  • 5
    @Quassnoi Хорошо. Я пробовал поместить его на sqlfiddle, но я отказался, так как каждый запрос, который я пытаюсь запустить, помимо создания схемы, истекает. Я понял, что просто удаление «EXISTS» также делает запрос корректным для меня. – Clox 16 May 2017 в 09:34

Предполагая, что ваша таблица имеет имя TableABC, а нужный столбец - это Col, а первичный ключ - T1 - Key.

SELECT a.Key, b.Key, a.Col 
FROM TableABC a, TableABC b
WHERE a.Col = b.Col 
AND a.Key <> b.Key

Преимущество этого подхода в этом ответе - это ключ .

9
ответ дан TechTravelThink 26 August 2018 в 05:47
поделиться
  • 1
    +1 Потому что это удобно. Хотя, по иронии судьбы, сам результат содержит дубликаты (он перечисляет a и b, затем b и a). – Fabien Snauwaert 19 May 2016 в 10:25
  • 2
    @FabienSnauwaert Вы можете избавиться от некоторых дубликатов, сравнив меньше (или больше) – Michael 25 October 2017 в 18:45
Select column_name, column_name1,column_name2, count(1) as temp from table_name group by column_name having temp > 1
1
ответ дан Vipin Jain 26 August 2018 в 05:47
поделиться
Другие вопросы по тегам:

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