删除sql中的重复项并相应地修改关系表

时间:2013-02-21 18:01:49

标签: mysql sql plsql mysql-workbench

我有三张桌子: menu_tab有列(menu_id,menu_description) item_tab有列(item_id,item_name,item_description,item_price) menu_has_item有列{(menu_tab_menu_id --->这是menu_id的外键(menu_tab中的pk)),item_tab_item_id ---是item_id的外键(item_tab中的pk))4

将会遇到两种重复 1)在同一menu_description中重复项目 2)项目副本在不同的菜单描述

示例:午餐菜单中有两个鸡肉三明治。午餐中的一个鸡肉三明治和晚餐菜单中的另一个鸡肉三明治_description

menu_tab    
menu_id menu_description
1        lunch
2        dinner
3        Specials


item_tab        
item_id item_description    
1       b 
2       d   
3       g   
4       x   
5       g          delete g
6       d   
7       e   
8       b          delete b
9       x   



menu_has_tab

menu_tab_menu_id item_tab_item_id
 1个............................ 1
1个............................ 2
1个............................ 3
1个............................ 4
2 ............................ 5替换为3
2个............................ 6
3个............................ 7
3 ............................ 8替换为1
3 ............................ 9

如何在删除重复项后使用替换后的值更新menu_has_item?

3 个答案:

答案 0 :(得分:1)

begin
  for x in (
            -- find duplicate items
            select *
              from (select rowid row_id,
                           item_id,
                           item_description,
                           row_number() over(partition by item_description order by
                           item_description) row_no
                       from item_tab)
            where row_no > 1) loop
-- replaceing duplicate Items
    update menu_has_item 
    set menu_has_item.item_tab_item_id =
           ( select item_id
              from (select item_id,
                           row_number() over(partition by item_description order by
                           item_description) row_no
                       from item_tab where 
                       item_tab.item_description = x.item_description)
             where row_no = 1)
   where menu_has_item .item_tab_item_id = x.item_id;
-- deleting duplicate items
     delete item_tab where rowid = x.row_id;
  end loop;
-- commit;
end;

答案 1 :(得分:0)

首先,您需要使用新值

替换menu_tab中的重复项
merge into menu_tab dest
using (select *
         from (select item_id, min(item_id) over(partition by item_description) as new_item_id from item_tab)
        where item_id != new_item_id) src
on (dest.item_tab_item_id = src.item_id)
when matched then
    update set dest.item_tab_item_id = new_item_id;

之后,您需要从项目表中删除重复项 你可以在那里找到脚本 http://sprogram.com.ua/en/articles/oracle-delete-duplicate-record

你把问题标记为plsql并且我认为你关于甲骨文,对不起。 但我在MySQL中存在合并声明 祝你好运

答案 2 :(得分:0)

我为我的表Rout(RoutID,SourceCityID,DestCityID)和Form(FormID,RoutID,...)做了这个 我删除了表Rout中的重复路径并更新了Form表中的RoutID
首先获取按要复制的列

分组的重复行
(SELECT * FROM
    Rout,
    (SELECT MIN(RoutID) MinRoutID
    FROM Rout,
        (SELECT SourceCityID,DestCityID
        FROM Rout
        GROUP BY SourceCityID,DestCityID
        HAVING count(*) > 1) AS Duplicates
    WHERE Rout.SourceCityID=Duplicates.SourceCityID AND Rout.DestCityID=Duplicates.DestCityID
    GROUP BY Rout.SourceCityID,Rout.DestCityID)AS MRCols
WHERE RoutID=MinRoutID)AS DuplicateGroup

然后获取所有重复的行而不进行分组,并使用将要比较重复的列

(SELECT RoutID,Rout.SourceCityID,Rout.DestCityID FROM Rout,
    (SELECT SourceCityID,DestCityID
    FROM Rout
    GROUP BY SourceCityID,DestCityID
    HAVING count(*) > 1)AS Duplicates
WHERE Rout.SourceCityID=Duplicates.SourceCityID AND Rout.DestCityID=Duplicates.DestCityID)AS DuplicateDetail

然后更新表格tbl,如下所示:

UPDATE Form SET RoutID=DuplicateGroup.RoutID
FROM
    Form,
    (SELECT * FROM
        Rout,
        (SELECT MAX(RoutID) MinRoutID
        FROM Rout,
            (SELECT SourceCityID,DestCityID
            FROM Rout
            GROUP BY SourceCityID,DestCityID
            HAVING count(*) > 1) AS Duplicates
        WHERE Rout.SourceCityID=Duplicates.SourceCityID AND Rout.DestCityID=Duplicates.DestCityID
        GROUP BY Rout.SourceCityID,Rout.DestCityID)AS MRCols
    WHERE RoutID=MinRoutID)AS DuplicateGroup
    ,
    (SELECT RoutID,Rout.SourceCityID,Rout.DestCityID FROM Rout,
        (SELECT SourceCityID,DestCityID
        FROM Rout
        GROUP BY SourceCityID,DestCityID
        HAVING count(*) > 1)AS Duplicates
    WHERE Rout.SourceCityID=Duplicates.SourceCityID AND Rout.DestCityID=Duplicates.DestCityID)AS DuplicateDetail
WHERE
    Form.RoutID=DuplicateDetail.RoutID AND
    DuplicateGroup.SourceCityID=DuplicateDetail.SourceCityID
    AND DuplicateGroup.DestCityID=DuplicateDetail.DestCityID

现在删除Rout中不在表格

中的行
DELETE FROM Rout WHERE RoutID NOT IN(SELECT DISTINCT RoutID FROM Form)