如何在MySQL中删除重复的连接表记录?

时间:2015-10-23 15:59:37

标签: mysql ruby-on-rails content-management-system relation data-cleaning

假设我有一个news_stories表,每个故事都可以通过related_stories表相互关联。

related_stories的架构是这样的:

related_stories
----------------
id: INT
story_id: INT
related_id: INT

一开始,没有人添加验证来防止2个故事之间存在多重关系,所以有时你最终会得到2个related_stories记录,如下所示:

id: 1, story_id: 3, related_id: 4

id: 2, story_id: 4, related_id: 3

从本质上讲,这是一个重复。

我现在可以添加一个验证来防止这种情况发生,但它并没有改变我仍有数千个重复记录(或创建相同关系的记录)这一事实。

我需要一些方法来清除这些旧的重复项,每个关系只留下一条记录。如果它全部基于单个字段,这将非常简单,但由于ID可以在任何一个字段中,对我来说似乎很棘手。

如何在MySQL中删除这些记录的重复项?出于某种原因,我不会发生这种情况。 Rails的解决方案也会受到欢迎,不过我更喜欢普通的MySQL。

2 个答案:

答案 0 :(得分:1)

删除最大的,最少的组合(保留1,2,删除2,1):

delete rel from rel join (
  select greatest(id1,id2) id1, least(id1,id2) id2
  from   rel
  group by least(id1,id2), greatest(id1,id2)
  having count(*) > 1
) d on rel.id1 = d.id1 and rel.id2 = d.id2;

您还可以修改以根据最小/最大ID保留一行。

答案 1 :(得分:0)

hash = {}
all_stories = RelatedStories.all.map{|rs| hash[rs.id] = [rs.story_id, rs.related_id].sort}

hash.select{|_id, data| hash.has_value?(data)}