본문 바로가기
MySql

MySQL delete duplicate records but keep latest

by 베이스 공부 2020. 10. 7.
반응형

고유 한 id email 필드가 있습니다. 이메일이 중복됩니다. 모든 중복 이메일 주소를 하나만 유지하고 싶지만 최신 id (마지막으로 삽입 된 레코드)를 사용하고 싶습니다.

이것을 어떻게 달성 할 수 있습니까?

 

해결 방법

 

테이블 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 

따라서 반복되는 모든 이메일을 찾아서 모두 삭제해야하지만 최신 ID는 삭제해야합니다.
이 경우 aaa , bbb eee 가 반복되므로 ID 1, 7, 2 및 6을 삭제하려고합니다.

이를 수행하려면 먼저 반복되는 모든 이메일을 찾아야합니다.

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

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

그런 다음이 데이터 세트에서 반복되는 각 이메일의 최신 ID를 찾아야합니다.

  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                                 

마지막으로 ID가 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   |
+----+-------+


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

 

참조 페이지 https://stackoverflow.com/questions/6107167

 

 

반응형

댓글