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 
    

    したがって、繰り返されるすべての電子メールを検索し、それらをすべて削除する必要がありますが、最新のIDです。
    この場合、aaabbb および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   |
    +----+-------+
    

    別のバージョンは、 ReneLimon によって提供された削除です。

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


    1. Hibernateネイティブクエリ-char(3)列

    2. postgresqlデータベースの所有者がデータベースにアクセスできません-リレーションが見つかりません。

    3. ハッシュ化されたパスワードフィールドに使用するデータ型と長さは?

    4. MySQL変換関数