Mysql 如何从这些重复项中清理数据库
我有一个包含以下字段的表: id |域名|域名|证书|编号|密钥值 select语句的输出示例如下: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',
'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*/)
。