डुप्लिकेट प्रविष्टियों को mysql db से कैसे निकालें?




duplicate-removal (6)

MySQL टेबल पर डुप्लिकेट हटाना एक सामान्य मुद्दा है, जो आमतौर पर विशिष्ट आवश्यकताओं के साथ आता है। अगर किसी को दिलचस्पी है, तो यहाँ ( MySQL में डुप्लिकेट पंक्तियाँ निकालें ) मैं समझाता हूँ कि कैसे एक विश्वसनीय और तेज़ तरीके से (विभिन्न उपयोग मामलों के लिए उदाहरण के साथ) MySQL डुप्लिकेट को हटाने के लिए एक अस्थायी तालिका का उपयोग करें।

इस मामले में, इस तरह से कुछ काम करना चाहिए:

-- create a new temporary table
CREATE TABLE tmp_table1 LIKE table1;

-- add a unique constraint    
ALTER TABLE tmp_table1 ADD UNIQUE(id, title);

-- scan over the table to insert entries
INSERT IGNORE INTO tmp_table1 SELECT * FROM table1 ORDER BY sid;

-- rename tables
RENAME TABLE table1 TO backup_table1, tmp_table1 TO table1;

मेरे पास कुछ आईडी + शीर्षकों के साथ एक तालिका है। मैं शीर्षक स्तंभ को अद्वितीय बनाना चाहता हूं, लेकिन इसमें पहले से ही 600k से अधिक रिकॉर्ड हैं, जिनमें से कुछ डुप्लिकेट (कभी-कभी कई दर्जन से अधिक बार) हैं।

मैं एक को छोड़कर सभी डुप्लिकेट कैसे निकालूं, इसलिए मैं शीर्षक कॉलम के बाद एक UNIQUE कुंजी जोड़ सकता हूं?


चूंकि MySql ALTER IGNORE TABLE dev.mysql.com/worklog/task/?id=7395 , इसलिए इंडेक्स को जोड़ने से पहले आपको वास्तव में डुप्लिकेट तारीख को हटाना होगा।

पहले एक क्वेरी लिखें जो सभी डुप्लिकेट्स को ढूंढती है। यहां मैं मान रहा हूं कि email वह क्षेत्र है जिसमें डुप्लिकेट हैं।

SELECT
    s1.email
    s1.id, 
    s1.created
    s2.id,
    s2.created 
FROM 
    student AS s1 
INNER JOIN 
    student AS s2 
WHERE 
    /* Emails are the same */
    s1.email = s2.email AND
    /* DON'T select both accounts,
       only select the one created later.
       The serial id could also be used here */
    s2.created > s1.created 
;

अगला केवल विशिष्ट डुप्लिकेट आईडी का चयन करें:

SELECT 
    DISTINCT s2.id
FROM 
    student AS s1 
INNER JOIN 
    student AS s2 
WHERE 
    s1.email = s2.email AND
    s2.created > s1.created 
;

एक बार जब आप सुनिश्चित हो जाते हैं कि केवल वही डुप्लिकेट आईडी शामिल हैं, जिन्हें आप हटाना चाहते हैं, हटाएं। आपको जोड़ना होगा (SELECT * FROM tblname) ताकि MySql को शिकायत न हो।

DELETE FROM
    student 
WHERE
    id
IN (
    SELECT 
        DISTINCT s2.id
    FROM 
        (SELECT * FROM student) AS s1 
    INNER JOIN 
        (SELECT * FROM student) AS s2 
    WHERE 
        s1.email = s2.email AND
        s2.created > s1.created 
);

फिर अद्वितीय सूचकांक बनाएं:

ALTER TABLE
    student
ADD UNIQUE INDEX
    idx_student_unique_email(email)
;

नीचे दिए गए क्वेरी का उपयोग सबसे कम "आईडी" फ़ील्ड मान वाली एक पंक्ति को छोड़कर सभी डुप्लिकेट को हटाने के लिए किया जा सकता है

DELETE t1 FROM table_name t1, table_name t2 WHERE t1.id > t2.id AND t1.name = t2.name

इसी तरह, हम पंक्ति को 'आईडी' में उच्चतम मान के साथ रख सकते हैं

 DELETE t1 FROM table_name t1, table_name t2 WHERE t1.id < t2.id AND t1.name = t2.name

मूल तालिका की अलग-अलग पंक्तियों के साथ एक नई तालिका बनाएं। अन्य तरीके भी हो सकते हैं लेकिन मुझे यह सबसे साफ लगता है।

CREATE TABLE tmp_table AS SELECT DISTINCT [....] FROM main_table

अधिक विशेष रूप से :
तेज़ तरीका अलग-अलग पंक्तियों को एक अस्थायी तालिका में सम्मिलित करना है। डिलीट का उपयोग करते हुए, मुझे 8 मिलियन पंक्तियों की तालिका से डुप्लिकेट को हटाने में कुछ घंटे लगे। इंसर्ट और विशिष्ट का उपयोग करते हुए, इसमें सिर्फ 13 मिनट का समय लगा।

CREATE TABLE tempTableName LIKE tableName;  
CREATE INDEX ix_all_id ON tableName(cellId,attributeId,entityRowId,value);  
INSERT INTO tempTableName(cellId,attributeId,entityRowId,value) SELECT DISTINCT cellId,attributeId,entityRowId,value FROM tableName;  
DROP TABLE tableName;  
INSERT tableName SELECT * FROM tempTableName;  
DROP TABLE tempTableName;  

यह दिखाता है कि इसे SQL2000 में कैसे किया जाता है। मैं MySQL सिंटैक्स से पूरी तरह परिचित नहीं हूँ, लेकिन मुझे यकीन है कि वहाँ कुछ तुलनीय है

create table #titles (iid int identity (1, 1), title varchar(200))

-- Repeat this step many times to create duplicates
insert into #titles(title) values ('bob')
insert into #titles(title) values ('bob1')
insert into #titles(title) values ('bob2')
insert into #titles(title) values ('bob3')
insert into #titles(title) values ('bob4')


DELETE T  FROM 
#titles T left join 
(
  select title, min(iid) as minid from #titles group by title
) D on T.title = D.title and T.iid = D.minid
WHERE D.minid is null

Select * FROM #titles

delete from student where id in (
SELECT distinct(s1.`student_id`) from student as s1 inner join student as s2
where s1.`sex` = s2.`sex` and
s1.`student_id` > s2.`student_id` and
s1.`sex` = 'M'
    ORDER BY `s1`.`student_id` ASC
)




duplicate-removal