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

SQLiteで重複行を選択する6つの方法

    次のクエリを使用して、SQLiteで重複する行を返すことができます。

    ここで、重複する行には、ID列を含むすべての列で重複する値が含まれています。

    サンプルデータ

    次のデータを含むテーブルがあるとします。

    SELECT * FROM Pets;

    結果:

    PetId  PetName  PetType
    -----  -------  -------
    1      Wag      Dog    
    1      Wag      Dog    
    2      Scratch  Cat    
    3      Tweet    Bird   
    4      Bark     Dog    
    4      Bark     Dog    
    4      Bark     Dog    

    最初の2行は重複しており、最後の3行も重複しています。これは、3つの列すべてに、重複する各行に同じ値が含まれているためです。

    オプション1

    次のクエリを使用して、重複している行の数を確認できます。

    SELECT 
        PetId,
        PetName,
        PetType,
        COUNT(*) AS "Count"
    FROM Pets
    GROUP BY 
        PetId,
        PetName,
        PetType
    ORDER BY PetId;

    結果:

    PetId  PetName  PetType  Count
    -----  -------  -------  -----
    1      Wag      Dog      2    
    2      Scratch  Cat      1    
    3      Tweet    Bird     1    
    4      Bark     Dog      3    
    >

    ここでは、すべての列で行をグループ化し、各グループの行数を返しました。これにより、行が一意であるか(カウントが1)、重複しているか(カウントが1より大きい)がわかります。

    カウントの降順で並べ替えることができるため、重複が最も多い行が最初に表示されます。

    SELECT 
        PetId,
        PetName,
        PetType,
        COUNT(*) AS "Count"
    FROM Pets
    GROUP BY 
        PetId,
        PetName,
        PetType
    ORDER BY Count(*) DESC;

    結果:

    PetId  PetName  PetType  Count
    -----  -------  -------  -----
    4      Bark     Dog      3    
    1      Wag      Dog      2    
    2      Scratch  Cat      1    
    3      Tweet    Bird     1    
    > オプション2

    重複する行のみをリストする場合は、HAVINGを使用できます。 カウントが1より大きい行のみを返す句

    SELECT 
        PetId,
        PetName,
        PetType,
        COUNT(*) AS "Count"
    FROM Pets
    GROUP BY 
        PetId,
        PetName,
        PetType
    HAVING COUNT(*) > 1
    ORDER BY PetId;

    結果:

    PetId  PetName  PetType  Count
    -----  -------  -------  -----
    1      Wag      Dog      2    
    4      Bark     Dog      3    
    オプション3

    もう1つのオプションは、ROW_NUMBER()を使用することです。 ウィンドウ関数:

    SELECT 
        *, 
        ROW_NUMBER() OVER ( 
            PARTITION BY PetId, PetName, PetType 
            ORDER BY PetId, PetName, PetType
            ) AS Row_Number
    FROM Pets;

    結果:

    PetId  PetName  PetType  Row_Number
    -----  -------  -------  ----------
    1      Wag      Dog      1         
    1      Wag      Dog      2         
    2      Scratch  Cat      1         
    3      Tweet    Bird     1         
    4      Bark     Dog      1         
    4      Bark     Dog      2         
    4      Bark     Dog      3         

    PARTITION BY 句は、FROMによって生成された結果セットを分割します 関数が適用されるパーティションへの句。結果セットにパーティションを指定すると、各パーティションによって番号付けが最初からやり直されます(つまり、各パーティションの最初の行の番号付けは1から始まります)。

    オプション4

    上記のクエリを一般的なテーブル式として使用できます:

    WITH cte AS 
        (
            SELECT 
                *, 
                ROW_NUMBER() OVER ( 
                    PARTITION BY PetId, PetName, PetType 
                    ORDER BY PetId, PetName, PetType
                    ) AS Row_Number
            FROM Pets
        )
    SELECT * FROM cte WHERE Row_Number <> 1;

    結果:

    PetId  PetName  PetType  Row_Number
    -----  -------  -------  ----------
    1      Wag      Dog      2         
    4      Bark     Dog      2         
    4      Bark     Dog      3         

    これにより、一致する重複から余分な行だけが返されます。したがって、同じ行が2つある場合は、そのうちの1つを返します。同一の行が3つある場合は、2つを返します。

    このクエリは、重複排除操作でテーブルから削除される行数を示すのに役立ちます。他のいくつかのDBMS(少なくともSQL Serverでは)では、最後のSELECT *を置き換えることができます DELETEを使用 テーブルから重複する行を削除します。しかし、SQLiteではCTEをそのように更新することはできません。

    幸い、次の2つのオプションは、削除を実行するように変更できます。

    オプション5

    SQLiteのrowidを利用できます :

    SELECT * FROM Pets
    WHERE EXISTS (
      SELECT 1 FROM Pets p2 
      WHERE Pets.PetName = p2.PetName
      AND Pets.PetType = p2.PetType
      AND Pets.rowid > p2.rowid
    );

    結果:

    PetId  PetName  PetType
    -----  -------  -------
    1      Wag      Dog    
    4      Bark     Dog    
    4      Bark     Dog    

    これはどのように作動しますか?デフォルトでは、SQLiteのすべての行には、通常rowidと呼ばれる特別な列があります 、テーブル内のその行を一意に識別します。これは必要に応じて削除できますが、明示的に削除されていない限り、クエリ内で活用できます。

    オプション6

    そして最後に、SQLiteのrowidを使用する別のオプションがあります :

    SELECT * FROM Pets
    WHERE rowid > (
      SELECT MIN(rowid) FROM Pets p2  
      WHERE Pets.PetName = p2.PetName
      AND Pets.PetType = p2.PetType
    );

    結果:

    PetId  PetName  PetType
    -----  -------  -------
    1      Wag      Dog    
    4      Bark     Dog    
    4      Bark     Dog    

    1. SQL Server:PARTITIONBYとGROUPBYの違い

    2. SQLServerチェックテーブルのパーティション化

    3. SQL Server(T-SQL)ですべての言語のリストを取得する方法

    4. MySQLUNION句