我有2个表:Tags和Post_Tags_relationship
标记表有3列 - ID(主要),标题和网址 Post_Tags_relationship表有2列 - Tag_ID AND Post_ID(主要是两者的组合)
Tags表中有很多类似的标签title和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```
如果我们从Tags表中删除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 :(得分:1)
查找标签重复并将其存储在“临时”表中:
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;
在posts_tags
中查找需要更新的条目。将它们存储在第三个“临时”表中:
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_id
中更新posts_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
现在定义正确的UNIQUE和FOREIGN键,这样您就不需要再次修复它了。
答案 1 :(得分:0)
我将概述如何解决这个问题,我会假设您的表格不大且查询费用不高:
从标记表中选择所有不同的标题,可以使用DISTINCT
关键字来完成。这将使标题不复制:
SELECT DISTINCT Title FROM Tag
循环生成的标题,并为每个标题的标签表创建一个新查询,以获取此特定标题的所有重复字段。您最终会获得具有相同标题的行。
循环具有相同标题的行,将其中的每一行替换为您要保留的ID,同时在Post_Tags_relationship中替换此ID。全部使用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
// ..
}