Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

MySQL menghapus catatan duplikat tetapi tetap terbaru

Bayangkan tabel Anda test berisi data berikut:

  select id, email
    from test;

ID                     EMAIL                
---------------------- -------------------- 
1                      aaa                  
2                      bbb                  
3                      ccc                  
4                      bbb                  
5                      ddd                  
6                      eee                  
7                      aaa                  
8                      aaa                  
9                      eee 

Jadi, kita perlu menemukan semua email berulang dan menghapus semuanya, kecuali id ​​terbaru.
Dalam hal ini, aaa , bbb dan eee diulang, jadi kami ingin menghapus ID 1, 7, 2 dan 6.

Untuk mencapai ini, pertama-tama kita perlu menemukan semua email yang berulang:

      select email 
        from test
       group by email
      having count(*) > 1;

EMAIL                
-------------------- 
aaa                  
bbb                  
eee  

Kemudian, dari kumpulan data ini, kita perlu menemukan id terbaru untuk setiap email yang berulang ini:

  select max(id) as lastId, email
    from test
   where email in (
              select email 
                from test
               group by email
              having count(*) > 1
       )
   group by email;

LASTID                 EMAIL                
---------------------- -------------------- 
8                      aaa                  
4                      bbb                  
9                      eee                                 

Akhirnya kami sekarang dapat menghapus semua email ini dengan Id yang lebih kecil dari LASTID. Jadi solusinya adalah:

delete test
  from test
 inner join (
  select max(id) as lastId, email
    from test
   where email in (
              select email 
                from test
               group by email
              having count(*) > 1
       )
   group by email
) duplic on duplic.email = test.email
 where test.id < duplic.lastId;

Saya belum menginstal mySql di mesin ini sekarang, tetapi seharusnya berfungsi

Perbarui

Penghapusan di atas berfungsi, tetapi saya menemukan versi yang lebih optimal:

 delete test
   from test
  inner join (
     select max(id) as lastId, email
       from test
      group by email
     having count(*) > 1) duplic on duplic.email = test.email
  where test.id < duplic.lastId;

Anda dapat melihat bahwa itu menghapus duplikat tertua, yaitu 1, 7, 2, 6:

select * from test;
+----+-------+
| id | email |
+----+-------+
|  3 | ccc   |
|  4 | bbb   |
|  5 | ddd   |
|  8 | aaa   |
|  9 | eee   |
+----+-------+

Versi lain, adalah penghapusan yang disediakan oleh Rene Limon

delete from test
 where id not in (
    select max(id)
      from test
     group by email)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Format tanggal MySQL – apa yang perlu Anda ketahui

  2. Apa solusi terbaik untuk penyatuan koneksi database dengan python?

  3. Meminta beberapa database sekaligus

  4. Apakah ada Profiler yang setara untuk MySql?

  5. Cara Membuat Script dari Diagram di MySQL Workbench