查找重复项,然后使用主表中的 id 更新表,然后删除表中的记录
Posted
技术标签:
【中文标题】查找重复项,然后使用主表中的 id 更新表,然后删除表中的记录【英文标题】:Find duplicates, then update a table with the id from the main table and then delete records in a table 【发布时间】:2019-07-25 14:46:06 【问题描述】:我的问题如下我有两个表,personaldata 表包含员工的记录,whoisonboard 表包含员工入职时的记录。我们在personaldata表中有重复,当人们登记入住时,这些不同的id也存储在whoisonboard表中。找到重复没有问题。
删除personal表中所有whoisonboard表中不存在的数据) 从个人数据中删除,其中 id 不在(从 whoisonboard 中选择 personid)
这将删除任何没有上过任何船只的人,因为 whoisonboard 表中不会有记录。
我们删除 whoisonboard 中没有相应个人数据记录的任何记录 - 这是为了确保没有孤立的 whoisonboard 记录
DELETE FROM whoisonboard WHERE personid NOT IN (SELECT id FROM personaldata)
我们可以在personaldata表中找到所有重复项并给出whoisonboard,识别重复项查询查找字段名称,date_of_birth和nationality是一样的。
select a.id as personid, b.id as whoisid, b.personid whoispersonid, a.names, a.date_of_birth, a.nationality
from personaldata a
join whoisonboard b on a.id = b.personid
where (a.names, a.date_of_birth, a.nationality) in (
select a.names, a.date_of_birth, a.nationality
from personaldata a
group by a.names, a.date_of_birth, a.nationality
having count(distinct a.id) > 1
)
order by date_of_birth desc
然后我们可以发出这条 SQL 语句来更新记录,然后删除重复项的孤立记录,如果我们有很多重复项,这样做会很耗时。
UPDATE whoisonboard SET personid = '74777a8e-343c-11e9-a2bb-000c2912dae9'
WHERE `id` LIKE '5bd2c268-ec4d-11e8-ab89-000c29045ceb'
最后,我会用
删除孤儿记录从 id 不在的个人数据中删除(从 whoisonboard 中选择 personid)
我一直在尝试构建一个可以一次性完成更新的 SQL 语句,它失败了
update whoisonboard set personid = final_id
from whoisonboard
join personaldata on personaldata.id = whoisonboard.personid
join ( select names, date_of_birth, nationality, min(id) as final_id from
personaldata group by names, date_of_birth, nationality ) min_ids on
min_ids.names = personaldata.names
执行时出现错误,我想知道我尝试做的事情是否可以在一个 sql 语句中执行,问题是当我们试图避免重复时,它们确实会发生,最好有一种简单的刷新方法数据库。
【问题讨论】:
【参考方案1】:我这样做只是为了纠正我的数据仓库中的一个类似问题。
我包含了很多伪代码,因为这很长,我不想为你的情况测试它。另外,我的是用于 SQL Server 的,所以代码可能不适合你。所以这是概念......
创建一个临时表来存储所有自然键代码组合和 id(每个自然键有许多 id)。
create table #p (id [auto_increment], personkey, personid)
insert #p select lastname + ',' + firstname, personid
from personaldata
order by 1
创建一个临时表来存储每个自然键值的最小 id(每个自然键一个 id)。
create table #pmin (id [auto_increment], personkey, personid)
insert #pmin
select personkey, min(personid) as personid
from #p
group by personkey
order by 1
遍历#pmin的记录,更新whoisonboard,整理persondata。
declare variables
initialize variables
loop through #pmin from id = 1 to [max]
begin loop
increment counter
store the values of personkey and personid for this iteration
select @thisVal = personkey, @idMin = personid from #pmin where id = @i
store all values of personid for this personkey from #p (I used a table variable @a)
insert @a select personid from #p where personkey = @thisVal
update whoisonboard set personid = min personid for all values of personid
update whoisonboard set personid = @idMin where personid in (select personid from @a)
delete all but the first persondata record for this iteration
delete persondata where personid in (select personid from @a where personid <> @idMin)
end loop
我的代码还包括我需要为我的案例执行的一些其他步骤,以及大量测试/数据比较代码,以验证我在每个步骤中都做了正确的事情。
报告每个人之前和之后的日期、工资或其他内容。它们应该完全匹配。 验证您获得了第一条和最后一条记录。 您认为合适的其他检查总的来说,我的代码大约有 600 行。 (这就是为什么我不想在这里达到那种程度的原因。)但是我在这里提供的内容应该足以完成您的任务。
【讨论】:
谢谢,我会回顾一下你所做的,看看我可以如何采用以上是关于查找重复项,然后使用主表中的 id 更新表,然后删除表中的记录的主要内容,如果未能解决你的问题,请参考以下文章
在 excel 365 中,在 2 个单独的工作表中查找重复数据,然后复制相邻的单元格数据