2011-05-04 242 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