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

Mysql 如何从这些重复项中清理数据库,mysql,Mysql,我有一个包含以下字段的表: id |域名|域名|证书|编号|密钥值 select语句的输出示例如下: '57092', '02a1fae.netsolstores.com', '02a1fae.netsolstores.com_1', '55525772666' '57093', '02a1fae.netsolstores.com', '02a1fae.netsolstores.com_2', '22225554186' '57094', '02a1fae.netsolstores.com',

我有一个包含以下字段的表: id |域名|域名|证书|编号|密钥值

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’
我需要清理我的数据库,以便:我想删除第一个
域\u证书\u no
重复
keyvalue
的域名(即,在本例中,我查找字段
domain\u certificate\u no
02aa6aa.netsolstores.com\u 1
,因为它是数字1,并且具有重复的密钥值,所以我想删除整个链,即
02aa6aa.netsolstores.com\u 2
02aa6aa.netsolstores.com\u 3
,通过删除域名这个连锁店所属的是
02aa6aa.netsolstores.com

如何自动化整个数据库的检查过程。因此,我有一个查询,可以检查模式
('.%.%)
编辑:中的任何域名,并且它们具有共享域名(在本例中:
netsolstores.com
),如果它发现属于该域名的证书编号1具有重复的键值,则删除。否则为否。请注意,如果不是1号,
域证书编号
具有重复的键值是可以的


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

我不确定您的示例中的“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)
还有其他更有效的表达方法(取决于数据库),但这保留了原始查询的结构


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

您能否澄清“删除链”一词位。如果您要删除
02aa6aa.netsolstores.com
以删除链,您保留了什么?是否存在需要
2
等的情况?在本例中,如果我删除:
02a1fae.netsolstores.com
,我将保留另一个域
02aa6aa.netsolstores.com
。换句话说,我不需要整个域链如果1号证书有重复密钥。没有任何情况下我需要删除2如果1号证书。但请记住我添加的编辑。比较是在共享域名但不同子级域名的域名之间。也就是说,如果有重复使用不同域名的情况,比如说,
02a1fae.msn.com
,那么就可以了。不需要与其他域名进行比较。在我看来,这是一个select语句。我需要删除重复的值。通常,当我尝试删除查询结果的记录时(在workbench中),它不允许我。它将其标记为只读。我不这样认为。我不需要为任何重复密钥保留最小值。我希望为共享该域名的域名保留任何重复密钥的最小值(在我的示例中,共享域名是:
netsolstores.com
)。调整Gordon的答案,直到它返回您要删除的行(当您删除大量行时,请确保这一点)。然后调整它,使其仅返回您要删除的行的id。然后执行
从t where id in删除(/*Select statement here*/)