У меня есть таблица со столбцом varchar, и я хотел бы найти все записи, которые имеют повторяющиеся значения в этом столбце. Какой лучший запрос я могу использовать, чтобы найти дубликаты?
У меня есть таблица со столбцом varchar, и я хотел бы найти все записи, которые имеют повторяющиеся значения в этом столбце. Какой лучший запрос я могу использовать, чтобы найти дубликаты?
Ответы:
Сделать SELECT
с GROUP BY
оговоркой. Допустим, имя - это столбец, в котором вы хотите найти дубликаты:
SELECT name, COUNT(*) c FROM table GROUP BY name HAVING c > 1;
Это вернет результат со значением имени в первом столбце и счетчиком того, сколько раз это значение появляется во втором столбце.
GROUP_CONCAT(id)
и он будет перечислять идентификаторы. Смотрите мой ответ для примера.
ERROR: column "c" does not exist LINE 1
?
SELECT varchar_col
FROM table
GROUP BY varchar_col
HAVING COUNT(*) > 1;
IN()
/ NOT IN()
.
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
Конечно, наличие индекса значительно ускорит этот запрос.
ORDER BY varchar_column DESC
в конец запроса.
GROUP BY
и HAVING
возвращает только один из возможных дубликатов. Кроме того, производительность с индексированным полем вместо COUNT(*)
, и возможность ORDER BY
группировать дубликаты записей.
Составив ответ levik, чтобы получить идентификаторы дублирующихся строк, вы можете сделать это, GROUP_CONCAT
если ваш сервер его поддерживает (это вернет список идентификаторов, разделенных запятыми).
SELECT GROUP_CONCAT(id), name, COUNT(*) c FROM documents GROUP BY name HAVING c > 1;
SELECT id, GROUP_CONCAT(id), name, COUNT(*) c [...]
она включает встроенное редактирование и должна обновлять все задействованные строки (или, по крайней мере, первую совпадающую строку), но, к сожалению, редактирование генерирует ошибку Javascript. ..
Предполагая, что ваша таблица называется 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
Преимущество этого подхода перед приведенным выше ответом заключается в том, что он дает ключ.
Чтобы узнать, сколько записей являются дубликатами в столбце имени в Employee, полезен следующий запрос;
Select name from employee group by name having count(*)>1;
чтобы получить все данные, которые содержат дубликаты, я использовал это:
SELECT * FROM TableName INNER JOIN(
SELECT DupliactedData FROM TableName GROUP BY DupliactedData HAVING COUNT(DupliactedData) > 1 order by DupliactedData)
temp ON TableName.DupliactedData = temp.DupliactedData;
TableName = таблица, с которой вы работаете.
DupliactedData = дублированные данные, которые вы ищете.
Мой последний запрос включал несколько ответов, которые мне помогли - объединение по группам, count & GROUP_CONCAT.
SELECT GROUP_CONCAT(id), `magento_simple`, COUNT(*) c
FROM product_variant
GROUP BY `magento_simple` HAVING c > 1;
Это обеспечивает идентификатор обоих примеров (через запятую), нужный мне штрих-код и количество дубликатов.
Измените таблицу и столбцы соответственно.
Я не вижу никаких подходов JOIN, которые имеют много применений с точки зрения дубликатов.
Этот подход дает вам реальные удвоенные результаты.
SELECT t1.* FROM my_table as t1
LEFT JOIN my_table as t2
ON t1.name=t2.name and t1.id!=t2.id
WHERE t2.id IS NOT NULL
ORDER BY t1.name
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
Замените город своей таблицей. Замените имя на имя вашего поля
Принимая @ maxyfc в ответ дальше, мне нужно , чтобы найти все из строк , которые были возвращены с повторяющимися значениями, так что я мог редактировать их в MySQL Workbench :
SELECT * FROM table
WHERE field IN (
SELECT field FROM table GROUP BY field HAVING count(*) > 1
) ORDER BY field
Я видел приведенный выше результат, и запрос будет работать нормально, если вам нужно проверить значение одного столбца, которые являются дубликатами. Например, электронная почта.
Но если вам нужно проверить больше столбцов и хотите проверить комбинацию результата, этот запрос будет работать нормально:
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)
SELECT COUNT(CONCAT(userid,event,datetime)) AS total, userid, event, datetime FROM mytable GROUP BY CONCAT(userid, event, datetime ) HAVING total>1
Я предпочитаю использовать оконные функции (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;
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
Далее будут найдены все 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
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)
SELECT DISTINCT a.email FROM `users` a LEFT JOIN `users` b ON a.email = b.email WHERE a.id != b.id;
a.email
чтобы a.*
и получить все идентификаторы строк с дубликатами.
SELECT DISTINCT a.*
решено почти мгновенно.
Для удаления повторяющихся строк с несколькими полями сначала сопоставьте их новому уникальному ключу, который указан только для отдельных строк, а затем используйте команду «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;
CREATE TEMPORARY TABLE ...
? Небольшое объяснение вашего решения было бы здорово.
Один очень поздний вклад ... на тот случай, если он поможет кому-то в конце концов ... У меня была задача найти подходящие пары транзакций (фактически обе стороны переводов со счета на счет) в банковском приложении, чтобы определить, какие из них были '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 секунды. Конечно, идентификатор транзакции является основным индексом, который действительно помог.
Select column_name, column_name1,column_name2, count(1) as temp from table_name group by column_name having temp > 1
SELECT ColumnA, COUNT( * )
FROM Table
GROUP BY ColumnA
HAVING COUNT( * ) > 1
Если вы хотите удалить дубликаты, используйте DISTINCT
В противном случае используйте этот запрос:
SELECT users.*,COUNT(user_ID) as user FROM users GROUP BY user_name HAVING user > 1;
Попробуйте использовать этот запрос:
SELECT name, COUNT(*) value_count FROM company_master GROUP BY name HAVING value_count > 1;