web-dev-qa-db-ja.com

SQLで重複する行を削除する

一意のIDを持つテーブルがありますが、行情報が重複しています。

このクエリを使用して、重複する行を見つけることができます

SELECT
    PersonAliasId, StartDateTime, GroupId, COUNT(*) as Count
FROM
    Attendance
GROUP BY
    PersonAliasId, StartDateTime, GroupId
HAVING
    COUNT(*) > 1

このクエリで必要な1を維持しながら、行を手動で削除できます

Delete
From Attendance
Where Id IN(SELECT
    Id
FROM
    Attendance
Where PersonAliasId = 15
    and StartDateTime = '9/24/2017'
and GroupId = 1429
Order By ModifiedDateTIme Desc
Offset 1 Rows)

最初のクエリの行を使用して、最新のものを残して重複を削除する方法を理解するのに十分なSQLに精通していません。これを手動で1つずつ実行する最初のクエリによって返される3481を超えるレコードがあります。

最初のクエリのように重複する行を見つけて、2番目のように最新のものを除いてすべて削除するにはどうすればよいですか?

4
Kevin Rutledge

Common Table Expression 重複を削除するには:

WITH Cte AS(
    SELECT *,
        Rn = ROW_NUMBER() OVER(PARTITION BY PersonAliasId, StartDateTime, GroupId 
                                ORDER BY ModifiedDateTIme DESC)
    FROM Attendance
)
DELETE FROM Cte WHERE Rn > 1;

これにより、各レコードの最新のレコードが保持されますPersonAliasId - StartDateTime - GroupIdの組み合わせ。

6
Felix Pamittan

MAX集約関数を使用して、各グループ/個人の組み合わせの最新の開始日時を識別します。次に、その最新の時刻を持たないレコードを削除します。

DELETE a
FROM attendance as a
INNER JOIN (  
   SELECT
        PersonAliasId, MAX(StartDateTime) AS LatestTime, GroupId,
    FROM
        Attendance
    GROUP BY
        PersonAliasId, GroupId
    HAVING
        COUNT(*) > 1
) as b
on a.personaliasid=b.personaliasid and a.groupid=b.groupid and a.startdatetime < b.latesttime
0
Greg Viers

CTEの回答と同じ-Felixに小切手を与える

delete 
from ( SELECT rn = ROW_NUMBER() OVER(PARTITION BY PersonAliasId, StartDateTime, GroupId 
                                     ORDER BY ModifiedDateTIme DESC)
        FROM Attendance
     ) tt 
where tt.rn > 1
0
paparazzo