我有一个带有指向字符串表的外键列的映射表。在字符串表中,有重复项(我打算删除)。在删除重复项之前,我想更新映射表,以便每个外键索引都指向所指向的字符串的第一个实例。
我正在使用的架构部分如下:
图像标记图
- imageTagMapId
- 图像标识
- 标记ID
图像标签
- 小叮当
- 标签名称
即,我将删除 tagName 的重复记录,但我需要 ImageTagMap 中的每个映射指向与被删除实例具有相同“tagName”的第一个标签。
谢谢!
我有一个带有指向字符串表的外键列的映射表。在字符串表中,有重复项(我打算删除)。在删除重复项之前,我想更新映射表,以便每个外键索引都指向所指向的字符串的第一个实例。
我正在使用的架构部分如下:
图像标记图
图像标签
即,我将删除 tagName 的重复记录,但我需要 ImageTagMap 中的每个映射指向与被删除实例具有相同“tagName”的第一个标签。
谢谢!
这是一个相当普遍的问题,实际上很容易解决(一旦你知道如何:)。
我创建了一些样本临时数据,其中包含 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 列上抛出唯一约束。
我最近不得不在 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;