更新映射表以修复重复项

时间:2014-06-04 15:59:47

标签: sql sql-server tsql

我有一个需要删除重复行的表。问题是这两行可能在其他表中都有相关的东西。我的表Table1看起来像这样:

PK | A | ...
----------------
1  | 1 | ...
2  | 5 | ...
3  | 1 | ...
....

因此,在这种情况下,第1行和第3行是重复的。我想保持最低PK的那个。我有另一个表Table2,它还有一个PK,所有行都由映射表Table1映射到T1T2Map。地图表如下所示:

PK | T1PK | T2PK
-----------------
1  | 1    | 2
2  | 5    | 6
3  | 3    | 7
....

我可以使用此查询获取Table1中的所有重复行:

SELECT PK FROM (SELECT ROW_NUMBER() OVER (PARTITION BY A ORDER BY PK) NO,*
        FROM Table1) AS T1 WHERE NO = 2

我想要做的是将3列中的所有T1PK更改为1

这是我更新0行的丑陋更新语句:

update T1T2Map
set PK =(SELECT PK FROM (SELECT ROW_NUMBER() OVER (PARTITION BY A ORDER BY PK) NO,*
            FROM Table1) AS T2 WHERE NO = 1 and T2.PrintKey = (SELECT A FROM Table1 WHERE PK = T1T2Map.T1PK))
where T1PK in(SELECT PK
    FROM (SELECT ROW_NUMBER() OVER (PARTITION BY A ORDER BY PK) NO,*
        FROM Table1) AS T1 WHERE NO = 2)

似乎应该有一种更简单的方法来做到这一点,但我很想念它 谢谢你的帮助。

1 个答案:

答案 0 :(得分:1)

这只是一个开始 你需要一个cte才能像列一样使用NO

with cte (PK,A,NO)
as  
(
    SELECT PK, A, 
           minPK = Min(PK) over (PARTITION BY A), 
           ROW_NUMBER() OVER (PARTITION BY A ORDER BY PK) NO
      FROM Table1
)
select cte.pk, cte.a, cte.minPK, change.T1PK  
  from cte   
  join T1T2Map as change 
    on change.T1PK = cte.PK 
   and cte.NO > 1 

我想你要设置change.T1PK = cte.minPK
我想您知道更新的工作原理 - 使用选择

进行测试

我认为这是更新
此更新

update T1T2Map 
   set change.T1PK = keep.T1PK
  from cte  
  join T1T2Map as keep 
    on keep.T1PK = cte.PK 
   and cte.NO = 1 
  join T1T2Map as change 
    on change.T1PK = cte.PK 
   and cte.NO > 1