当多个字段共同提供唯一ID

时间:2016-11-08 11:20:20

标签: sql ms-access duplicates sql-delete

我有一个历史人口普查数据库表,其中四个字段共同标识每个人。这四个字段代表不同级别的政府领域,使得表格如下:

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;

2 个答案:

答案 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在评论中所建议的那样,最简单的方法是执行以下操作:

  1. (创建表格结构的副本)[http://www.techrepublic.com/article/copy-an-existing-table-structure-into-a-new-access-database/];
  2. 制作四个键KOMMNRKRETSNRBOSTNRPERSNR主键(在设计视图中打开结构表,为这些键选择四行,以及然后单击主键按钮);
  3. 然后创建一个追加查询以将数据插入新表。
  4. 执行这些步骤后,我按照希望得到的帖子比原始表少了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个帖子,这是预期)。