2011-05-04 240 views
20

我有一張表應該保留給定配置文件(用戶id到用戶id對)的訪問者的蹤跡。事實證明,我的SQL查詢有點偏離,正在按照預期生成多個對,而不是單個對。事後看來,我應該對每個id + id對執行一個唯一的約束。刪除除一個重複記錄以外的所有記錄

現在,我怎麼可以去清理桌子?我想要做的是刪除所有重複的對,只留下一個。

因此,例如更改此:

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 
+0

什麼是表結構嗎?是否有第三列來打破價值? – gbn 2011-05-04 11:31:19

+0

@gbn:已添加表結構(MySQL)。第三列是保留用戶最後一次訪問配置文件的軌跡。該結構應該可以通過對profile_id&visitor_id的約束來修改。 P.S:我現在沒有填充表格的SQL,但它是'if exists update timestamp if not create record'行的。 – 2011-05-04 11:39:07

回答

36

使用組由一個子查詢:

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

你需要某種獨特的標識符(在這裏,我使用的是ID)。

UPDATE

正如@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 
); 
+1

偉大的解決方案。我沒有想過(經驗>知識)使用一個組。這會顯示'不能在FROM子句中指定目標',但是有一個解決方法(請參閱我的答案)。 – 2011-05-04 11:58:34

+2

請注意,這在MySQL中不起作用,因爲它不允許您修改您在內部選擇中使用的表格: '錯誤代碼:1093.您無法指定目標表'my_tab'進行更新FROM子句' – Desty 2016-03-03 13:44:46

+0

同樣的錯誤在這裏。它不起作用 – VipinS 2016-05-21 08:37:19

2

選擇所有獨特的行
將它們複製到一個新的臨時表
截斷原始表
複製臨時表的數據原始表

這我會做什麼。我不確定是否有一個查詢可以爲你做這一切。

+0

使用臨時表是一個很好的反射,實際上是必要的。如果有大量數據,這可能是一種更適應的方法。 – 2011-05-04 12:03:10

12

這裏是弗蘭克·施密特的解決方案有一個小的解決方法臨時表:

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 
) 
+0

@FrankSchmitt這是完美的:) – 2016-05-30 06:43:46

1

這將工作:

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