sql >> データベース >  >> RDS >> SQLite

SQLiteで主キーを持つ重複行を削除する6つの方法

    以下は、SQLiteのテーブルから重複する行が主キーまたは一意の識別子列を持っている場合にそれらの行を削除する6つの例です。

    このような場合、重複を比較するときは主キーを無視する必要があります(主キーは定義上重複行を防ぐため)。

    サンプルデータ

    この例では、次のデータを使用しています。

    SELECT * FROM Dogs;

    結果:

    DogId  FirstName  LastName
    -----  ---------  --------
    1      Bark       Smith   
    2      Bark       Smith   
    3      Woof       Jones   
    4      Ruff       Robinson
    5      Wag        Johnson 
    6      Wag        Johnson 
    7      Wag        Johnson 

    最後の3行と同様に、最初の2行に重複が含まれていることがわかります。

    DogId 列は一意の値を保持するため(テーブルの主キーであるため)、厳密に言えば、重複はありません。しかし、実際の状況では、主キーを含むテーブルの重複を排除したい場合がよくあります。したがって、次の例では、主キーを無視し、残りの列で重複する値を含む行を削除します。

    オプション1

    上記の表を重複排除するための最初のオプションは次のとおりです。

    DELETE FROM Dogs 
    WHERE DogId IN (
        SELECT DogId FROM Dogs 
        EXCEPT SELECT MIN(DogId) FROM Dogs 
        GROUP BY FirstName, LastName
        );
    
    SELECT * FROM Dogs;

    結果:

    DogId  FirstName  LastName
    -----  ---------  --------
    1      Bark       Smith   
    3      Woof       Jones   
    4      Ruff       Robinson
    5      Wag        Johnson 

    テーブルは期待どおりに重複排除されています。

    または、MAX()を使用することもできます MIN()の代わりに関数 削除する行を変更する関数。次の例でこれを行います。

    オプション2

    この例(および次の例)では、テーブルが(重複して)元の状態に復元されていると想定します。

    重複する行を削除して残りの行を選択する別のクエリは次のとおりです。

    DELETE FROM Dogs WHERE DogId IN (
        SELECT d2.DogId 
        FROM Dogs d1, Dogs d2 
        WHERE d1.FirstName = d2.FirstName 
        AND d1.LastName = d2.LastName 
        AND d1.DogId <> d2.DogId 
        AND d1.DogId=( 
            SELECT MAX(DogId) 
            FROM Dogs d3 
            WHERE d3.FirstName = d1.FirstName 
            AND d3.LastName = d1.LastName
        )
    );
    
    SELECT * FROM Dogs;

    結果:

    DogId  FirstName  LastName
    -----  ---------  --------
    2      Bark       Smith   
    3      Woof       Jones   
    4      Ruff       Robinson
    7      Wag        Johnson 

    これで、テーブルの重複が解除されました。

    MAX()を使用したことに注意してください MIN()の代わりに関数 前の例で使用しました。これが重複排除操作に与える影響を確認できます。テーブルからさまざまな行を削除しました。

    オプション3

    MIN()を使用する必要のないオプションは次のとおりです または MAX()

    DELETE FROM Dogs
    WHERE EXISTS (
      SELECT 1 FROM Dogs d2 
      WHERE Dogs.FirstName = d2.FirstName
      AND Dogs.LastName = d2.LastName
      AND Dogs.DogId > d2.DogId
    );
    
    SELECT * FROM Dogs;

    結果:

    DogId  FirstName  LastName
    -----  ---------  --------
    1      Bark       Smith   
    3      Woof       Jones   
    4      Ruff       Robinson
    5      Wag        Johnson 
    オプション4

    別のオプションは次のとおりです:

    DELETE FROM Dogs
    WHERE DogId > (
      SELECT MIN(DogId) FROM Dogs d2  
      WHERE Dogs.FirstName = d2.FirstName
      AND Dogs.LastName = d2.LastName
    );
    
    SELECT * FROM Dogs;

    結果:

    DogId  FirstName  LastName
    -----  ---------  --------
    1      Bark       Smith   
    3      Woof       Jones   
    4      Ruff       Robinson
    5      Wag        Johnson 
    オプション5

    デフォルトでは、SQLiteのすべての行には、通常rowidと呼ばれる特別な列があります 、テーブル内のその行を一意に識別します。テーブルから明示的に削除されていない限り、これを各行の一意の識別子として使用できます。この方法は、何らかの理由で主キーを参照できない場合(または、テーブルに主キーがない場合)に役立つ可能性があります。

    したがって、rowidを使用できます DogIdの代わりにクエリで 列:

    DELETE FROM Dogs
    WHERE EXISTS (
      SELECT 1 FROM Dogs d2 
      WHERE Dogs.FirstName = d2.FirstName
      AND Dogs.LastName = d2.LastName
      AND Dogs.rowid > d2.rowid
    );
    
    SELECT * FROM Dogs;

    結果:

    DogId  FirstName  LastName
    -----  ---------  --------
    1      Bark       Smith   
    3      Woof       Jones   
    4      Ruff       Robinson
    5      Wag        Johnson 
    オプション6

    これが他の例ですが、rowid 主キーの代わりに:

    DELETE FROM Dogs
    WHERE rowid > (
      SELECT MIN(rowid) FROM Dogs d2  
      WHERE Dogs.FirstName = d2.FirstName
      AND Dogs.LastName = d2.LastName
    );
    
    SELECT * FROM Dogs;

    結果:

    DogId  FirstName  LastName
    -----  ---------  --------
    1      Bark       Smith   
    3      Woof       Jones   
    4      Ruff       Robinson
    5      Wag        Johnson 

    1. MySQL挿入クエリから新しいレコードの主キーIDを取得しますか?

    2. Android-すでに閉じられているオブジェクトを再度開こうとします:loaderManagerを使用してSQLiteQuery

    3. 次のイベントの日付を表示する

    4. 最大値を見つけて、SQLサーバーの別のフィールドから対応する値を表示します