6

I have a MySQL table like:

ID, Col1, Col2, Col3, Col4, etc...

ID is a primary key and has been working since the table's creation.

What I want to do is delete all but one records where all the other columns are identical.

DineshDB
  • 5,998
  • 7
  • 33
  • 49
giggsey
  • 933
  • 2
  • 11
  • 31
  • possible duplicate of [Remove duplicate rows in MySQL](http://stackoverflow.com/questions/3311903/remove-duplicate-rows-in-mysql) – Basilevs Sep 16 '14 at 15:52

8 Answers8

13
DELETE DupRows.*
FROM MyTable AS DupRows
   INNER JOIN (
      SELECT MIN(ID) AS minId, col1, col2
      FROM MyTable
      GROUP BY col1, col2
      HAVING COUNT(*) > 1
   ) AS SaveRows ON SaveRows.col1 = DupRows.col1 AND SaveRows.col2 = DupRows.col2
      AND SaveRows.minId <> DupRows.ID;

Of course you have to extend col1, col2 in all three places to all columns.

Edit: I just pulled this out of a script I keep and re-tested, it executes in MySQL.

Christo
  • 8,729
  • 2
  • 22
  • 16
1
  1. RENAME TABLE [table w/ duplicates] TO [temporary table name]

  2. Create an identical table with the original table name which contained the duplicates.

  3. INSERT INTO [new table] SELECT DISTINCT * FROM [old table with duplicates]

  4. Delete the temporary tables.

Ian Gregory
  • 5,770
  • 1
  • 29
  • 42
1

Without nested selects or temporary tables.

DELETE  t1
FROM    table_name t1, table_name t2
WHERE   
            (t1.Col1 = t2.Col1 OR t1.Col1 IS NULL AND t2.Col1 IS NULL)
        AND (t1.Col2 = t2.Col2 OR t1.Col2 IS NULL AND t2.Col2 IS NULL)
        AND (t1.Col3 = t2.Col3 OR t1.Col3 IS NULL AND t2.Col3 IS NULL)
        AND (t1.Col4 = t2.Col4 OR t1.Col4 IS NULL AND t2.Col4 IS NULL)
        ...
        AND t1.ID < t2.ID;
Basilevs
  • 22,440
  • 15
  • 57
  • 102
0

You can try this with the help of join : Like that way:

DELETE e1 FROM emp_tbl AS e1 JOIN emp_tbl AS e2 WHERE 
e1.Col1=e2.Col1 AND e1.Col2=e2.Col2 AND e1.Col3=e2.Col3 AND e1.Col4=e2.Col4
AND e1.id < e2.id;
Lakhan
  • 12,328
  • 3
  • 19
  • 28
0

You can run an alter query and achieve this:

ALTER IGNORE TABLE tbl_1
ADD UNIQUE INDEX unq_idx(col1, col2, col3);

I cant guarantee it will retain the first record among the duplicates, but MySQL usually does that.

georgecj11
  • 1,600
  • 15
  • 22
0

I'd do it following way, in MSSQL, but I think it should work with slight modifications in MySQL. Not executable, but should show the way.

CREATE TEMPORARY TABLE #Table (Col1, Col2, Col3);
INSERT INTO #Table (Col1, Col2, Col3) SELECT DISTINCT Col1, Col2, Col3 FROM Table;
DELETE FROM Table;
INSERT INTO Table (Col1, Col2, Col3) SELECT Col1, Col2, Col3 FROM #Table;
DROP TABLE #Table;
nothrow
  • 15,882
  • 9
  • 57
  • 104
0

you can also do this

Create table new_table{id, col1,col2,col3}

insert into new_table values(select distinct * from old_table)

drop table old_table
Lalit Chattar
  • 704
  • 4
  • 10
  • 24
  • 1
    This isn't really a practical solution. Works for pet project but start degrading quickly in a production environment. You're going to rename your table because you have duplicates? What if you have code running against the old table with queries that need to be updated to match the new table name? – Dave Apr 09 '13 at 19:42
0

you can delete all the rows except one by using some function like Min(depends on db). Ex:

delete from Table_Name
where Id not in
( select min(Id)
from  Table_Name
group by ID, Col1, Col2, Col3, Col4);
Swagatika
  • 3,376
  • 6
  • 30
  • 39