由于数据迁移的问题,表A中有重复的记录。
表A有两行具有相同名称“ Jason”,其ID为1和3。我想将所有外键引用从Link A和Link B中的id = 3移到1,然后删除Jason的记录,ID = 3,来自表A。
表A
id name column2 column3
-------------------------------------
1 Jason text text
2 Alice text text
3 Jason text text
链接A
id column1 tableA_ID
----------------------------
1 text 1
2 text 2
3 text 3
链接B
id column1 tableA_ID
----------------------------
1 text 1
2 text 3
3 text 2
目前,我的简单解决方案是
--update ids
UPDATE db_A.`Link_A` SET id = 1 WHERE tableA_ID = 3;
UPDATE db_A.`Link_B` SET id = 1 WHERE tableA_ID = 3;
--delete ids
DELETE db_A.`Table_A` WHERE id = 3;
生产服务器上有大量受影响的ID,所以我在考虑是否有更好的解决方案。
答案 0 :(得分:0)
我将获得需要更新的值到临时表中,并使用该值进行所有更新。您可以使用CTE或子查询,但是将其放在#表中对我来说似乎很方便,并简化了更新。因此,请先执行此操作,然后使用#表进行更新:
select a.id originalId, b.minId updatedId
from Table_A a
join (select name, min(id) minId
from Table_A
group by name
having count(*) > 1) b on a.name = b.name
and a.id != b.minId
答案 1 :(得分:0)
我已在临时表中复制了您的DDL,此解决方案看起来不错。 您只需要对tbl B做同样的事情,它应该可以工作。无论如何,请首先在生产表的副本中进行验证:
-- Added DDL for my tables to allow easy testing to everybody:
SELECT * INTO #tblA
FROM (
SELECT 1 AS ID, 'Jason' AS [Name], 'text' AS column2, 'text' AS column3
UNION
SELECT 2 AS ID, 'Alice' AS [Name], 'text' AS column2, 'text' AS column3
UNION
SELECT 3 AS ID, 'Jason' AS [Name], 'text' AS column2, 'text' AS column3
) T1;
SELECT * INTO #tblLinkA
FROM (
SELECT 1 AS ID, 'text' AS column1, 1 AS tableA_ID
UNION
SELECT 2 AS ID, 'text' AS [Name], 2 AS tableA_ID
UNION
SELECT 3 AS ID, 'text' AS [Name], 3 AS tableA_ID
) T1;
SELECT * FROM #tblA;
SELECT * FROM #tblLinkA;
WITH DUP AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY Name, column2, column3 ORDER BY ID) AS Row,
MIN(ID) OVER (PARTITION BY Name, column2, column3) AS ID_Related
FROM #tblA) -- SELECT * FROM Dup ORDER BY ID;
UPDATE #tblLinkA
SET #tblLinkA.tableA_ID = DUP.ID_Related
FROM DUP
WHERE #tblLinkA.tableA_ID = DUP.ID
and DUP.Row > 1;
WITH DUP AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY Name, column2, column3 ORDER BY ID) AS Row,
MIN(ID) OVER (PARTITION BY Name, column2, column3) AS ID_Related
FROM #tblA)
DELETE FROM DUP
WHERE Row > 1;
SELECT * FROM #tblA;
SELECT * FROM #tblLinkA;