2

我有一个带有指向字符串表的外键列的映射表。在字符串表中,有重复项(我打算删除)。在删除重复项之前,我想更新映射表,以便每个外键索引都指向所指向的字符串的第一个实例。

我正在使用的架构部分如下:

图像标记图

  • imageTagMapId
  • 图像标识
  • 标记ID

图像标签

  • 小叮当
  • 标签名称

即,我将删除 tagName 的重复记录,但我需要 ImageTagMap 中的每个映射指向与被删除实例具有相同“tagName”的第一个标签。

谢谢!

4

2 回答 2

3

这是一个相当普遍的问题,实际上很容易解决(一旦你知道如何:)。

我创建了一些样本临时数据,其中包含 4 个标签(2 个重复的 2 个标签)和 2 个图像。每个图像有 2 个标签,但图像指向同一标签的不同版本。

最后,你得到 2 张图片,每张有 2 个标签,然后你可以删除其他 2 个标签:

如何修复它

select ROW_NUMBER() OVER(PARTITION BY #ImageTag.tagName ORDER BY #ImageTag.tagName) as TagRank, #ImageTagMap.imageTagMapId, #ImageTagMap.imageId, #ImageTag.tagId, #ImageTag.tagName
into #UpdateTable1
from #ImageTagMap
    join #ImageTag on #ImageTagMap.tagId = #ImageTag.tagId

select #UpdateTable1.tagId AS idToDelete, RowToKeep.tagId AS idToKeep
into #UpdateTable2
from #UpdateTable1
    join (select * from #UpdateTable1 where TagRank = 1) RowToKeep ON #UpdateTable1.tagName = RowToKeep.tagName
where #UpdateTable1.TagRank != 1

-- update the data
update #ImageTagMap
set tagId = #UpdateTable2.idToKeep
from #ImageTagMap
    join #UpdateTable2 ON #ImageTagMap.tagId = #UpdateTable2.idToDelete

-- verify the data
select *
from #ImageTagMap
    join #ImageTag on #ImageTagMap.tagId = #ImageTag.tagId

-- delete the dupes
delete #ImageTag
from #ImageTag
    left outer join #ImageTagMap on #ImageTag.tagId = #ImageTagMap.tagId
where #ImageTagMap.imageTagMapId is null

让我知道这是否适合你。

如果不应该允许重复,您还应该考虑在 tagName 列上抛出唯一约束。

于 2013-05-11T19:10:59.590 回答
1

我最近不得不在 SQL Server 中执行此操作。基本上它是以下 SQL 的变体。我有重复的属性 ID。您想设置 ORDER BY 以便结果按照您要保留的顺序在您要保留的顺序之前的顺序排列。

WITH numbered AS (
SELECT ROW_NUMBER() OVER(PARTITION BY attribute_id ORDER BY attribute_id) AS _dupe_num,
[attribute_id] FROM [dbo].[asset_attr] WHERE 1=1)

-- Change this to Delete after
SELECT * FROM numbered WHERE _dupe_num > 1;
于 2013-05-11T18:23:15.643 回答