0

这个来源很好,但太慢了。功能:如果 SC 和 %%5 和 2013.07.11 < date < 2013.07.18 和一些较旧的行代表行,则选择所有行方法:查找 X 计数行。一一看28天是否有一致性

select efi_name, efi_id, count(*) as dupes, id, mlap_date
from address m
where 
mlap_date > "2013.07.11"
and mlap_date < "2013.07.18"  
and mlap_type = "SC"
and calendar_id not like "%%5"

and  concat(efi_id,irsz,ucase(city), ucase(address)) in (
    select concat(k.efi_id,k.irsz,ucase(k.city), ucase(k.address)) as dupe
    from address k
    where k.mlap_date > adddate(m.`mlap_date`,-28)
    and k.mlap_date < m.mlap_date
    and k.mlap_type = "SC"
    and k.calendar_id not like "%%5"
    and k.status = 'Befejezett'
    group by concat(k.efi_id,k.irsz,ucase(k.city), ucase(k.address))
    having (count(*) > 1)
)
group by concat(efi_id,irsz,ucase(city), ucase(address))

感谢您的帮助!

4

2 回答 2

1

NOT LIKE加上通配符前缀的术语是索引使用的杀手。

您也可以尝试将IN+ 内联表替换为inner join: 优化器是否运行NOT LIKE两次查询(请参阅您的解释计划)?

看起来您可能正在使用 MySql,在这种情况下,您可以基于

efi_id 
irsz
ucase(city)
ucase(address))

并直接比较该列。这是在 MySql 中实现哈希联接的一种方式。

于 2013-07-20T09:13:01.227 回答
0

我认为您不需要子查询来执行此操作。您应该能够仅使用外部group by和条件聚合来做到这一点。

select efi_name, efi_id,
       sum(case when mlap_date > "2013.07.11" and mlap_date < "2013.07.18" then 1 else 0 end) as dupes, 
       id, mlap_date
from address m
where mlap_type = 'SC' and calendar_id not like '%%5'
group by efi_id,irsz, ucase(city), ucase(address)
having sum(case when m.status = 'Befejezett' and
                     m.mlap_date <= '2013.07.11' and
                     k.mlap_date > adddate(date('2013.07.11'), -28)
                then 1
                else 0
           end) > 1

这会产生与您的查询略有不同的结果。它不是查看每条记录之前的 28 天,而是查看该周期间的所有记录,然后查看该期间之前的 4 周。尽管存在这种细微的差异,但它仍然会在一周前的四个星期内识别出骗子。

于 2013-07-20T10:43:21.523 回答