如何从这些重复项中清理我的数据库

时间:2012-08-07 21:16:11

标签: mysql

我有一个包含以下字段的表: id |域名| domain_certificate_no |键值

select语句输出的示例可以是:

'57092', '02a1fae.netsolstores.com', '02a1fae.netsolstores.com_1', '55525772666'
'57093', '02a1fae.netsolstores.com', '02a1fae.netsolstores.com_2', '22225554186'
'57094', '02a1fae.netsolstores.com', '02a1fae.netsolstores.com_3', '22444356259'
'97168', '02aa6aa.netsolstores.com', '02aa6aa.netsolstores.com_1', '55525772666'
'97169', '02aa6aa.netsolstores.com', '02aa6aa.netsolstores.com_2', '22225554186'
'97170', '02aa6aa.netsolstores.com', '02aa6aa.netsolstores.com_3', '22444356259’

我需要清理我的数据库,以便:我想删除第一个keyvalue重复domain_certificate_no的域名(即,在此示例中,我查找字段{{1 }}:domain_certificate_no,因为它是数字1,并且具有重复的键值,那么我想删除整个链02aa6aa.netsolstores.com_102aa6aa.netsolstores.com_2,这样就删除了域名此链所属的名称为02aa6aa.netsolstores.com_3

如何自动完成整个数据库的检查过程。所以,我有一个查询,检查模式02aa6aa.netsolstores.com 编辑:中的任何域名,如果找到证书,他们有共享域名(在此例外:('%.%.%))没有。属于此域名的1具有重复的键值,然后删除。否则没有。请注意,如果netsolstores.com不是数字1,domain_certificate_no可以有重复值。

编辑:我只比较同一二级域名的重复过的代价。例如:在这个问题中,我比较了共享域名的值:.netsolstores.com。如果我有另一个域名,使用sublevel域名,我也会这样做。但重点是我不需要比较整个数据库。只有具有共享域名的值(但不同的子域名)。

1 个答案:

答案 0 :(得分:0)

我不确定你的例子中'02aa6aa.netsolstores.com_1'会发生什么。

以下仅保留任何重复键的最小ID:

with t as (
     select t.*,
            substr(domain_certificate_no,
                   instr(domain_certificate_no, '_') + 1, 1000) as version,
            left(domain_certificate_no, instr(domain_certificate_no, '_') - 1) as dcn
     from t
    )
select t.*
from t join
     (select keyvalue, min(dcn) as mindcn
      from t
      group by keyvalue
     ) tsum
     on t.keyvalue = tsum.keyvalue and
        t.dcn = tsum.mindcn 

对于您提供的数据,这似乎可以解决问题。这不会返回重复的“_1”版本。如果这很重要,可以很容易地修改查询。

虽然我更喜欢更积极(考虑要保留而不是删除行),但以下内容应删除您想要的内容:

with t as (
     select t.*,
            substr(domain_certificate_no,
                   instr(domain_certificate_no, '_') + 1, 1000) as version,
            left(domain_certificate_no, instr(domain_certificate_no, '_') - 1) as dcn
     from t
    ),
    tokeep as (
     select t.*
     from t join
          (select keyvalue, min(dcn) as mindcn
           from t
           group by keyvalue
          ) tsum
          on t.keyvalue = tsum.keyvalue and
             t.dcn = tsum.mindcn
    )
delete from t
where t.id not in (select id from tokeep)

还有其他表达方式可能更有效(取决于数据库)。但是,这会保留原始查询的结构。

顺便说一下,在尝试新的DELETE代码时,请确保存储表的副本。使用DELETE(和UPDATE)很容易出错。例如,如果省略WHERE子句,在记录所有这些行的漫长痛苦过程之后,所有行都将消失。您可能会发现,只需在新表中选择所需的结果,验证它们,然后截断旧表并重新插入它们就会更快。