У мене є таблиця зі стовпчиком 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 - ключ.
SELECT a.Key, b.Key, a.Col
FROM TableABC a, TableABC b
WHERE a.Col = b.Col
AND a.Key <> b.Key
Перевага такого підходу перед вищезазначеною відповіддю полягає в тому, що він дає ключ.
Щоб дізнатись, скільки записів є дублікатами у стовпці імен у співробітнику, корисний наступний запит;
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 = дублюються дані, які ви шукаєте.
Мій остаточний запит містив декілька відповідей, які допомогли - об’єднати групу, підрахунок та 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 ...
? Трохи пояснення вашого рішення було б чудово.
Один дуже пізній внесок ... на випадок, коли він допомагає кому-небудь перейти до лінійки ... У мене було завдання знайти пари транзакцій (насправді обидві сторони переказів з рахунку на рахунок) у банківській програмі, щоб визначити, які з них були "від" і "до" для кожної транзакції з переказу між рахунками, тому ми закінчили це:
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;