मेरे पास एक 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 *
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
डुप्लिकेट रिकॉर्ड समूह की संभावना ।
डुप्लिकेट पंक्तियों की आईडी प्राप्त करने के लिए लेविक के उत्तर का निर्माण आप कर सकते हैं 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 [...]
यह इनलाइन एडिटिंग को सक्षम करता है और इसमें शामिल सभी पंक्तियों को अपडेट करना चाहिए (या कम से कम पहले वाला मेल खाता है), लेकिन दुर्भाग्य से एडिट एक जावास्क्रिप्ट त्रुटि उत्पन्न करता है। ..
मान लें कि आपकी तालिका का नाम 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;
तालिका नाम = वह तालिका जिसके साथ आप काम कर रहे हैं।
डुप्लिकेटेडडाटा = जिस डुप्लीकेट डेटा की आप तलाश कर रहे हैं।
मेरी अंतिम क्वेरी में कुछ उत्तरों को शामिल किया गया है जो मदद करते हैं - समूह के आधार पर, गणना और GROUP_CONCAT का संयोजन।
SELECT GROUP_CONCAT(id), `magento_simple`, COUNT(*) c
FROM product_variant
GROUP BY `magento_simple` HAVING c > 1;
यह दोनों उदाहरणों की आईडी प्रदान करता है (अल्पविराम से अलग), बारकोड मुझे चाहिए, और कितने डुप्लिकेट।
तदनुसार तालिका और कॉलम बदलें।
मैं कोई जॉइन दृष्टिकोण नहीं देख रहा हूं, जिसमें डुप्लिकेट के संदर्भ में कई उपयोग हैं।
यह दृष्टिकोण आपको वास्तविक दोगुना परिणाम देता है।
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
@ Maxyfc के उत्तर को और आगे ले जाते हुए , मुझे उन सभी पंक्तियों को खोजने की आवश्यकता थी, जिन्हें डुप्लिकेट मानों के साथ लौटाया गया था, इसलिए मैं उन्हें MySQL कार्यक्षेत्र में संपादित कर सकता हूं :
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.*
लगभग तुरंत हल करने के लिए बदल रहा है ।
कई फ़ील्ड्स के साथ डुप्लिकेट पंक्तियों को हटाने के लिए, पहले उन्हें नई विशिष्ट कुंजी को निर्दिष्ट करें जो केवल विशिष्ट पंक्तियों के लिए निर्दिष्ट है, फिर उसी नई अद्वितीय कुंजी के साथ डुप्लिकेट पंक्तियों को हटाने के लिए "आदेश" समूह का उपयोग करें:
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
पहले एक तक सुरक्षित बनाता है , इस प्रकार सभी डुप्लिकेट मैचों को समाप्त करता है। लगभग 2 मिलियन रिकॉर्ड्स के जरिए दौड़े और सिर्फ 2 सेकंड में 12,000+ मैचों की पहचान की। बेशक लेन-देन प्राथमिक सूचकांक है, जिसने वास्तव में मदद की।
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;