Bir varchar sütun içeren bir tablo var ve bu sütunda yinelenen değerleri olan tüm kayıtları bulmak istiyorum. Yinelenenleri bulmak için kullanabileceğim en iyi sorgu nedir?
Bir varchar sütun içeren bir tablo var ve bu sütunda yinelenen değerleri olan tüm kayıtları bulmak istiyorum. Yinelenenleri bulmak için kullanabileceğim en iyi sorgu nedir?
Yanıtlar:
Bir Do SELECT
a ile GROUP BY
maddede. Diyelim ki ad , kopyalarını bulmak istediğiniz sütundur:
SELECT name, COUNT(*) c FROM table GROUP BY name HAVING c > 1;
Bu , ilk sütundaki ad değeri ve ikincisinde bu değerin kaç kez göründüğü ile ilgili bir sonuç döndürür .
GROUP_CONCAT(id)
ve kimlikleri listeleyecektir. Bir örnek için cevabımı görün.
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
)
Bu sorgu sadece farklı değil, tam kayıtları döndürür varchar_column
.
Bu sorgu kullanılmıyor COUNT(*)
. Çok sayıda yinelenen varsa COUNT(*)
, pahalıdır ve bütüne COUNT(*)
ihtiyacınız yoksa, aynı değere sahip iki satır olup olmadığını bilmeniz gerekir.
varchar_column
Tabii ki, bir dizin olması bu sorguyu büyük ölçüde hızlandıracaktır.
ORDER BY varchar_column DESC
Sorgunun sonuna ekledim .
GROUP BY
ve HAVING
olası kopyaların tek döner. Ayrıca, yerine dizinli alan ile performans COUNT(*)
ve ORDER BY
yinelenen kayıtları gruplandırma imkanı .
Yinelenen satırların kimliklerini almak için levik yanıtından yola çıkarak GROUP_CONCAT
, sunucunuz destekliyorsa yapabilirsiniz (bu, virgülle ayrılmış kimlik listesi döndürür).
SELECT GROUP_CONCAT(id), name, COUNT(*) c FROM documents GROUP BY name HAVING c > 1;
SELECT id, GROUP_CONCAT(id), name, COUNT(*) c [...]
satır içi düzenlemeyi etkinleştirir ve ilgili tüm satırları (veya en azından ilk eşleşen) güncellemelidir, ancak maalesef düzenleme bir Javascript hatası oluşturur. ..
Tablonuzun TableABC olduğunu ve istediğiniz sütunun Col ve T1'in birincil anahtarının Anahtar olduğunu varsayarsak.
SELECT a.Key, b.Key, a.Col
FROM TableABC a, TableABC b
WHERE a.Col = b.Col
AND a.Key <> b.Key
Bu yaklaşımın yukarıdaki cevaba göre avantajı, Anahtarı vermesidir.
Çalışan adı sütununda kaç kaydın yinelenen olduğunu bulmak için aşağıdaki sorgu yardımcı olur;
Select name from employee group by name having count(*)>1;
çoğaltma içeren tüm verileri almak için ben bu kullanılır:
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 = birlikte çalıştığınız tablo.
DupliactedData = aradığınız yinelenen veriler.
Son sorgum, gruplara göre gruplama, GROUP_CONCAT sayısını birleştirmek için burada yardımcı olan birkaç cevabı içeriyordu.
SELECT GROUP_CONCAT(id), `magento_simple`, COUNT(*) c
FROM product_variant
GROUP BY `magento_simple` HAVING c > 1;
Bu, her iki örneğin de kimliğini (virgülle ayrılmış), ihtiyacım olan barkodu ve kaç kopya olduğunu gösterir.
Tabloyu ve sütunları uygun şekilde değiştirin.
Çoğaltmalar açısından birçok kullanımı olan herhangi bir JOIN yaklaşımı görmüyorum.
Bu yaklaşım size gerçek iki katına çıkmış sonuçlar verir.
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
Şehri Masanızla değiştirin . Adı alan adınızla değiştirin
@ Maxyfc'nin cevabını daha fazla alarak , yinelenen değerlerle döndürülen tüm satırları bulmam gerekiyordu , bu yüzden onları MySQL Workbench'te düzenleyebilirim :
SELECT * FROM table
WHERE field IN (
SELECT field FROM table GROUP BY field HAVING count(*) > 1
) ORDER BY field
Yukarıdaki sonucu gördüm ve yinelenen tek sütun değerini kontrol etmeniz gerekiyorsa sorgu iyi çalışır. Örneğin e-posta.
Ancak daha fazla sütunla kontrol etmeniz gerekiyorsa ve bu sorgunun iyi çalışabilmesi için sonucun kombinasyonunu kontrol etmek istiyorsanız:
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
Ben tüm satır görebiliyordu çünkü çoğaltmaları bulmak için pencereli işlevleri (MySQL 8.0+) kullanmayı tercih ederim:
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
Aşağıda birden çok kez kullanılan tüm ürün_kileri bulunur. Her ürün_kimliği için yalnızca tek bir kayıt alırsınız.
SELECT product_id FROM oc_product_reward GROUP BY product_id HAVING count( product_id ) >1
Kodu alınan: 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
için a.*
ve tekrarlar da tüm satırları kimliklerini olsun.
SELECT DISTINCT a.*
neredeyse anında çözüldü.
Birden çok alana sahip yinelenen satırları kaldırmak için, önce bunları yalnızca farklı satırlar için belirtilen yeni benzersiz anahtara yönlendirin, ardından aynı yeni benzersiz anahtarla yinelenen satırları kaldırmak için "gruplama" komutunu kullanın:
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 ...
? Çözümünüzün küçük bir açıklaması harika olurdu.
Çok geç bir katkı ... herkesin hattan aşağı inmesine yardımcı olması durumunda ... Bir bankacılık uygulamasında eşleşen işlemleri çiftlerini (aslında hesaptan hesaba transferlerin her iki tarafı) bulmak, hangilerini belirlemek için bir görevim vardı her hesaplar arası aktarım işlemi için 'from' ve 'to' idi, bu yüzden bununla sonuçlandık:
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;
Sonuç olarak, DuplicateResultsTable
eşleşen (yani yinelenen) işlemleri içeren satırlar sağlanır, ancak aynı çiftle ikinci kez eşleştiğinde tersine aynı işlem kimlikleri sağlanır, böylece dış SELECT
, yapılan ilk işlem kimliğine göre gruplandırılır. kullanarak LEAST
ve GREATEST
emin iki transactionId en için güvenli kılar sonuçlarında aynı sırada, her zaman yapmak GROUP
böylece tüm yinelenen eşleşmeleri eleyecek, ilkine göre. Yaklaşık bir milyon kayıttan geçti ve 2 saniyenin altında 12.000'den fazla maç belirledi. Tabii işlem kimliği gerçekten yardımcı olan birincil endekstir.
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
Yinelenen kullanımı kaldırmak istiyorsanız DISTINCT
Aksi takdirde bu sorguyu kullanın:
SELECT users.*,COUNT(user_ID) as user FROM users GROUP BY user_name HAVING user > 1;
Bu sorguyu kullanmayı deneyin:
SELECT name, COUNT(*) value_count FROM company_master GROUP BY name HAVING value_count > 1;