2017-02-19 41 views
2

我有2個表:標籤和Post_Tags_relationshipMySQL的刪除/合併類似的行,它的引用

變量表有3列 - ID(主),標題和URL Post_Tags_relationship表有2列 - TAG_ID和Post_ID(主要是兩者的組合)

標籤表中有很多類似的標籤標題和URL,我想要刪除所有複製的記錄並修改Post_Tags_relationship以更新已存在的已刪除標籤ID一個,如果此更新將返回重複的id錯誤,然後將其刪除。

所以,如果標籤表有:

ID= 20, Title = News Section, URL = news-section 
ID= 68, Title = News Section, URL = news-section 

Post_Tags_relationship有:

Post_ID = 56, Tag_ID = 20 
Post_ID = 80, Tag_ID = 20 
Post_ID = 500, Tag_ID = 68 
Post_ID = 584, Tag_ID = 20 
Post_ID = 695, Tag_ID = 20 
Post_ID = 695, Tag_ID = 68``` 

如果我們從標籤表中刪除ID 20時,Post_Tags_relationship看起來像:

Post_ID = 56, Tag_ID = 68 
Post_ID = 80, Tag_ID = 68 
Post_ID = 500, Tag_ID = 68 
Post_ID = 584, Tag_ID = 68 
Post_ID = 695, Tag_ID = 68 // deplicate Primary key I want this to be removed please. 
Post_ID = 695, Tag_ID = 68 // ``` 

我希望這是有道理的,如果您有任何問題,請告訴我。

+0

你如何確定要保留哪個Tag_ID? –

+0

無關緊要,只要此標記的相關帖子轉換爲現有標記,就可以刪除任何標記。 –

+0

@AhmedEssam謝謝 –

回答

0

查找標籤副本,並將其儲存在一個「臨時」表:posts_tags

drop table if exists tmp_tags_duplicates; 
create table tmp_tags_duplicates 
    select t1.id, min(t0.id) as duplicate_of 
    from tags t1 
    join tags t0 using(title, url) 
    where t1.id > t0.id 
    group by t1.id; 

查找已插入重複(這需要刪除)。它們存儲在另一個「臨時」表:posts_tags

drop table if exists tmp_to_delete; 
create table tmp_to_delete 
    select pt1.*, d.duplicate_of 
    from posts_tags pt1 
    join tmp_tags_duplicates d on d.id = pt1.tag_id 
    join posts_tags pt0 
     on pt0.post_id = pt1.post_id 
     and pt0.tag_id = d.duplicate_of; 

查找條目需要被更新。將它們儲存在第三個 「臨時」 表:

drop table if exists tmp_to_update; 
create table tmp_to_update 
    select pt1.*, d.duplicate_of 
    from posts_tags pt1 
    join tmp_tags_duplicates d on d.id = pt1.tag_id 
    left join posts_tags pt0 
     on pt0.post_id = pt1.post_id 
     and pt0.tag_id = d.duplicate_of 
    where pt0.tag_id is null; 

刪除重複項posts_tags

delete pt 
from posts_tags pt 
join tmp_to_delete t using(post_id, tag_id); 

更新tag_idposts_tags

update posts_tags pt 
join tmp_to_update t using(post_id, tag_id) 
set pt.tag_id = t.duplicate_of; 

tags表中刪除重複

delete t 
from tags t 
join tmp_tags_duplicates using(id); 

刪除「臨時」表。

drop table tmp_tags_duplicates; 
drop table tmp_to_delete; 
drop table tmp_to_update; 

演示:http://rextester.com/FUWZG89399

現在定義適當的唯一性和外鍵,這樣你就不會需要以後再解決它。

+0

非常感謝Paul,這個答案似乎解決了這個問題,我會在早上測試它,當我接近我的筆記本電腦時。 –

+0

謝謝你隊友,這工作 –

0

我會給你一個大綱我會怎麼處理這個問題,我會假設你的表是不是很大,查詢並不昂貴:

  1. 選擇從標記表,所有不同的標題,這可以使用DISTINCT關鍵字完成。這將給標題,而不復制:

    SELECT DISTINCT方法,從標籤

  2. 循環所產生的冠軍,並作出新的查詢到標記表中每部影片都能獲得所有重複場爲這一特定稱謂。你最終會得到具有相同標題的行。

  3. 將具有相同標題的行循環替換爲要保留的ID,並同時在Post_Tags_relationship中替換此標識。所有與UPDATE聲明

進行,以避免在以後的使用外鍵這樣的問題。 https://www.w3schools.com/sql/sql_foreignkey.asp

更新:

爲了避免這種情況發生,因爲重複的主鍵,你可以創建一個數組,並在循環添加到它的每一個帖子ID,如果文章ID已經存在,刪除錯誤這個記錄來自表格。事情是這樣的:

$post_ids = array() 
//... 
// Duplicate fields loop 
if (in_array($pid, $post_ids)) { 
// The post has the tag already 
// Delete this record from table 
// .. 

} else { 
    $post_ids[] = $pid 
    // Update fields 
    // .. 
} 
+0

但是在某些情況下,uodate關係表將返回重複的主鍵錯誤。 –

+0

謝謝,明天我會看看。 –