在一个表中,我有三列-id,name和count。很多名称列是相同的(由于早期缺少UNIQUE),我想解决此问题。但是,id列由其他(4或5,我认为-我必须检查文档)表使用来查找名称,只是删除它们会破坏事情。因此,有没有一种很好的,干净的说法:“查找所有相同的记录并将它们合并在一起”?
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
为了解决您提到的问题,即合并表中具有相同名称但不同ID的记录,并且考虑到删除这些重复记录会破坏与其它表的关联性,您可以采用以下步骤来实现数据的清理和整合:
name
列有重复值,而每行记录都有唯一的id
。id
列被其他4或5个表作为外键使用,直接删除重复项会影响这些关联表的数据完整性。首先,创建一个新的临时表(我们称其为temp_cleaned_table
),用于存放去重后的数据。这个表需要包含所有原始列以及一个额外的列,比如merge_id
,用于标识哪些记录是合并过的。
CREATE TABLE temp_cleaned_table (
id INT,
name VARCHAR(255),
count INT,
merge_id INT
);
执行查询以找出所有具有相同name
的记录,并为它们分配相同的merge_id
。这里可以使用窗口函数ROW_NUMBER()来实现:
WITH CTE_Duplicates AS (
SELECT id, name, count,
ROW_NUMBER() OVER (PARTITION BY name ORDER BY id) as row_num
FROM original_table
)
INSERT INTO temp_cleaned_table (id, name, count, merge_id)
SELECT id, name, SUM(count), MIN(id) as merge_id
FROM CTE_Duplicates
GROUP BY name, row_num;
此步骤中,我们按name
分组并排序,为每个组内的记录分配一个递增的行号。然后,对每个名字组,我们只保留一行(例如,可以选择最小的id
作为代表),并将count
列的值相加,以此来“合并”具有相同名字的记录。
对于那些依赖于original_table.id
作为外键的其他表,您需要更新这些表中的外键引用,将指向重复id
的记录改为指向新确定的merge_id
。这一步较为复杂,可能需要逐个表进行处理,示例SQL如下(假设有一个关联表related_table
,其外键为fk_id
):
UPDATE related_table
SET fk_id = t.merge_id
FROM (
SELECT id, MIN(id) as merge_id
FROM original_table
GROUP BY name
HAVING COUNT(*) > 1
) t
WHERE related_table.fk_id = t.id;
在确保所有关联表的外键已正确更新后,可以考虑用temp_cleaned_table
替换原来的表,或者直接在原表上执行更新操作(如果支持且影响范围可控的话)。
通过以上步骤,您可以有效地解决名称重复问题,同时保持与关联表的一致性,避免了直接删除带来的副作用。