我有一个历史人口普查数据库表,其中四个字段共同标识每个人。这四个字段代表不同级别的政府领域,使得表格如下:
KOMMNR KRETSNR BOSTNR PERSNR FORNVN ETTNVN
[mncpl] [area] [rsdnc] [prsn] [firstn] [lastn] ← english
0101 001 0001 001 John Doe
0101 001 0001 002 Richard Doe
0101 001 0001 003 Johnny Doe
0101 001 0002 001 Jane Doe
可以看出,通过组合市政,地区,居住地和人的四个数字(短文本格式)来识别个人。个人ID号已添加到其他数据库,但目前正在等待实施。
我目前正在处理的数据库大约有900个帖子,我最终得到了大约12k个重复项,我需要删除它。表[T3 3 clean]中的示例:
KOMMNR KRETSNR BOSTNR PERSNR FORNVN ETTNVN
[mncpl] [area] [rsdnc] [prsn] [firstn] [lastn] ← english
0101 001a 0003 5 Ole Christian Elingsen
0101 001a 0003 5 Ole Christian Elingsen
1101 001a 0003 6 Kristian Johannesen
1101 001a 0003 6 Kristian Johannesen
2101 001a 0004 14 Jens Tøger Jensen
2101 001a 0004 14 Jens Tøger Jensen
我已阅读并查看了here提供的答案,但无法理解如何将其应用于我正在使用的结构中,原因有两个:我们的数据库结合多个字段来创建准每个人的唯一ID;并且由于没有单一的增量数字,我相信我无法应用那个优秀答案中提供的方法。
我想要完成的是删除每个副本。我在MS Access 2013本地工作。
更新:由于数据是公开可用的,托管在我们的Oracle服务器上,因此我在本地执行的操作以后可由其他人重现。但是,我不认为解决方案也可以直接在Oracle上运行,因为任何想要重现我的发现的人都会下载数据并在本地工作。
我目前不知道从哪里开始编写代码,只选择每个副本中的一个,然后删除它们,所以我无法提供样本。我试过运行SELECT DISTINCT *
,但最终我没有响应;显然有太多的数据来处理这样的查询,即使在减少的12k样本集上运行它也是如此。
以下是我选择重复项的方法:
SELECT
KOMMNR, KRETSNR, BOSTNR, PERSNR,
NYHUSH, FORNVN, ETTNVN,
BOSTAT, SEDVBO, ANTOPP, BYGNING,
KJONN, FAMST, SIVST, YRKE,
FAAR, FSTED, FSTED_KODE,
STATSB, TROSSMF, SYKDOM, SYKVAR,
BOSTNVN, FORNVNS, ETTNVNS,
PID
FROM [T3 3 FAAR rensket]
WHERE (
(([T3 3 FAAR rensket].KOMMNR) In (
SELECT KOMMNR FROM [T3 3 FAAR rensket] As Tmp
GROUP BY KOMMNR, KRETSNR, BOSTNR, PERSNR HAVING Count(*)>1
and KRETSNR = [T3 3 FAAR rensket].KRETSNR
and BOSTNR = [T3 3 FAAR rensket].BOSTNR
and PERSNR = [T3 3 FAAR rensket].PERSNR
)
)
)
ORDER BY KOMMNR, KRETSNR, BOSTNR, PERSNR;
答案 0 :(得分:0)
这基本上是您的查询:
SELECT r.*
FROM [T3 3 FAAR rensket] as r
WHERE r.KOMMNR In (SELECT KOMMNR
FROM [T3 3 FAAR rensket] As r2
GROUP BY KOMMNR, KRETSNR, BOSTNR, PERSNR
HAVING Count(*) > 1 AND
r2.KRETSNR = r.KRETSNR AND
r2.BOSTNR = r.BOSTNR AND
r2.PERSNR = r.PERSNR
)
ORDER BY KOMMNR, KRETSNR, BOSTNR, PERSNR;
第一条建议:将相关子句移到WHERE
子句:
SELECT r.*
FROM [T3 3 FAAR rensket] as r
WHERE r.KOMMNR In (SELECT r2.KOMMNR
FROM [T3 3 FAAR rensket] As r2
WHERE r2.KRETSNR = r.KRETSNR AND
r2.BOSTNR = r.BOSTNR AND
r2.PERSNR = r.PERSNR
GROUP BY KOMMNR, KRETSNR, BOSTNR, PERSNR
HAVING Count(*) > 1
)
ORDER BY KOMMNR, KRETSNR, BOSTNR, PERSNR;
其次,在[T3 3 FAAR rensket](KRETSNR, BOSTNR, PERSNR, KOMMNR)
上添加索引。
看看这些是否有助于提升表现。
答案 1 :(得分:0)
正如@ DarrenBartrup-Cook在评论中所建议的那样,最简单的方法是执行以下操作:
KOMMNR
,KRETSNR
,BOSTNR
和PERSNR
主键(在设计视图中打开结构表,为这些键选择四行,以及然后单击主键按钮); 执行这些步骤后,我按照希望得到的帖子比原始表少了5926个,通过错误消息不祥地报告。
似乎我获得重复条目的原因 - 尽管创建了包含大量附加内容的表 - 是因为我没有任何实际的主键。如果没有主键,Access无法知道两个字段是否相互重复
我计算确认结果(由Karl-Erlend Mikalsen提供(非常类似于@GordonLinoff建议的解决方案)):
SELECT x.KOMMNR,
x.KRETSNR,
x.BOSTNR,
x.PERSNR,
x.antall
FROM ( SELECT A.KOMMNR,
A.KRETSNR,
A.BOSTNR,
A.PERSNR,
COUNT (*) AS antall
FROM [T3 3 FAAR rensket] A
GROUP BY A.KOMMNR,
A.KRETSNR,
A.BOSTNR,
A.PERSNR) AS X
WHERE x.antall > 1;
(注意:这需要一个名为“x”的虚拟表才能工作。
正如预期的那样(并且非常希望)这会产生0个帖子,而相同的查询但是最后一行更改为WHERE x.antall = 1;
产生了预期的891724个帖子(相对于原始原始表中的894262个帖子,这是预期)。