Mysql
 sql >> база данни >  >> RDS >> Mysql

MySQL изтрива дублиращи се записи, но запазва най-новите

Представете си вашата таблица test съдържа следните данни:

  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 

И така, трябва да намерим всички повтарящи се имейли и да изтрием всички, но последния идентификатор.
В този случай aaa , bbb и eee се повтарят, така че искаме да изтрием идентификатори 1, 7, 2 и 6.

За да постигнем това, първо трябва да намерим всички повтарящи се имейли:

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

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

След това от този набор от данни трябва да намерим най-новия идентификатор за всеки един от тези повтарящи се имейли:

  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                                 

Накрая вече можем да изтрием всички тези имейли с идентификатор, по-малък от LASTID. Така че решението е:

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;

В момента нямам инсталиран mySql на тази машина, но трябва да работи

Актуализиране

Горното изтриване работи, но намерих по-оптимизирана версия:

 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;

Можете да видите, че изтрива най-старите дубликати, т.е. 1, 7, 2, 6:

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

Друга версия е изтриването, предоставено от 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. Прости произволни извадки от Sql база данни

  2. Как да изтрия от select в MySQL?

  3. MySql таблица Вмъкнете, ако не съществува, в противен случай актуализирайте

  4. Загубена връзка с MySQL сървър по време на заявка

  5. Как да предоставим всички привилегии на root потребител в MySQL 8.0