0

Скажем, у меня есть таблица news_stories, и каждая из этих историй может быть связана друг с другом через таблицу related_stories.Как удалить дубликаты записей таблицы соединений в MySQL?

Схема 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

В сущности, это дублирование.

Теперь я могу добавить подтверждение, чтобы это не произошло, но это не меняет того факта, что у меня все еще есть тысячи дубликатов записей (или записей, которые создают одинаковые отношения).

Мне нужно как-то очистить эти старые дубликаты, оставив только одну запись за отношения. Это было бы довольно просто, если бы все было основано на одном поле, но поскольку идентификаторы могут быть в любом поле, мне кажется сложным.

Как удалить дубликаты этих записей в MySQL? По какой-то причине это просто не происходит. Решения для Rails также приветствуются, хотя я бы предпочел простой MySQL.

+0

Связаны ли связанные_источники с уникальным столбцом id, или это всего лишь два столбца: story_id, related_id? – JRD

+0

Существует уникальный столбец идентификатора. Я просто оставил это для простоты. Я отредактирую свой вопрос, чтобы включить его для ясности. – Ravenstine

ответ

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.

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)}