web-dev-qa-db-ja.com

1つを除いてすべて重複するレコードを削除する

特定のプロファイルへの訪問者の追跡を保持することになっているテーブルがあります(ユーザーIDとユーザーIDのペア)。私のSQLクエリは少しずれていて、意図したように単一のペアではなく複数のペアを生成していることがわかりました。後から考えると、IDとIDの各ペアに一意の制約を適用する必要がありました。

さて、どうすればテーブルを片付けることができますか?私がやりたいことは、重複するペアをすべて削除して、1つだけ残します。

たとえば、次のように変更します。

23515 -> 52525 date_visited
23515 -> 52525 date_visited
23515 -> 52525 date_visited
12345 -> 54321 date_visited
12345 -> 54321 date_visited
12345 -> 54321 date_visited
12345 -> 54321 date_visited
23515 -> 52525 date_visited
...

これに:

23515 -> 52525 date_visited
12345 -> 54321 date_visited

更新:要求されたテーブル構造は次のとおりです。

id  int(10)         UNSIGNED    Non     Aucun   AUTO_INCREMENT
profile_id  int(10)         UNSIGNED    Non     0 
visitor_id  int(10)         UNSIGNED    Non     0
date_visited    timestamp           Non     CURRENT_TIMESTAMP   
33
James P.

サブクエリでgroup byを使用します。

delete from my_tab where id not in 
(select min(id) from my_tab group by profile_id, visitor_id);

なんらかの一意の識別子が必要です(ここでは、idを使用しています)。

[〜#〜]更新[〜#〜]

@JamesPoulsonが指摘したように、これはMySQLで構文エラーを引き起こします。正しい解決策は次のとおりです(- James 'answer に示すように):

delete from `my_tab` where id not in
( SELECT * FROM 
    (select min(id) from `my_tab` group by profile_id, visitor_id) AS temp_tab
);
48
Frank Schmitt

一時テーブルの小さな回避策を使用したフランクシュミットのソリューションを次に示します。

delete from `my_tab` where id not in
( SELECT * FROM 
    (select min(id) from `my_tab` group by profile_id, visitor_id) AS temp_tab
)
14
James P.

これは動作します:

With NewCTE
AS
(
Select *, Row_number() over(partition by ID order by ID)as RowNumber from 
table_name
)
Delete from NewCTE where RowNumber > 1
3
Vik Wilder

すべての一意の行を選択
それらを新しい一時テーブルにコピーします
元のテーブルを切り捨て
一時テーブルのデータを元のテーブルにコピーします

それが私がしたいことです。これをすべて行うクエリが1つあるかどうかはわかりません。

2
gmadd