如何在MySQL中找到共享相同(未知)前缀的字符串组?

如何在MySQL中找到共享相同(未知)前缀的字符串组?,mysql,regex,mariadb,Mysql,Regex,Mariadb,我正在我的论坛中搜寻垃圾邮件发送者,并注意到垃圾邮件发送者经常会以以下方式使用雅虎或Gmail的电子邮件地址: abcde*******01@gmail.com abcde*******02@gmail.com abcde*******03@gmail.com 它们将获取一串相同的字符,后跟随机乱码。通常,但不总是以随机数字结束 为了找到这些,我想找出所有与至少两个其他帐户共享相同前五个字符的用户电子邮件地址。我在删除之前手动检查这些,所以不必太担心偶尔出现的误报 这五个字符将是随机的,我不知

我正在我的论坛中搜寻垃圾邮件发送者,并注意到垃圾邮件发送者经常会以以下方式使用雅虎或Gmail的电子邮件地址:

abcde*******01@gmail.com
abcde*******02@gmail.com
abcde*******03@gmail.com
它们将获取一串相同的字符,后跟随机乱码。通常,但不总是以随机数字结束

为了找到这些,我想找出所有与至少两个其他帐户共享相同前五个字符的用户电子邮件地址。我在删除之前手动检查这些,所以不必太担心偶尔出现的误报

这五个字符将是随机的,我不知道他们提前,只是他们在多个帐户的电子邮件共享

我如何在MySQL中做到这一点

我猜我只需要从地址上切下前五个字符,然后按这个片段分组,计数大于2


但是我不知道正确的MySQL语法是什么。我怀疑它可以在没有正则表达式的情况下编写,不过如果有必要,我使用的是MariaDB 10,它提供了几个方便的基于正则表达式的SQL函数。

试试MySQL子字符串函数:

select SUBSTRING(email,1,5),count(*) from users group by 1 having count(*)>2 

尝试MySQL子字符串函数:

select SUBSTRING(email,1,5),count(*) from users group by 1 having count(*)>2 
不过,我觉得会很慢

编辑:这将在同一电子邮件地址可能多次出现的表中工作,如访问日志。如果所有电子邮件都是不同的,那么马修斯的解决方案也可以

不过,我觉得会很慢


编辑:这将在同一电子邮件地址可能多次出现的表中工作,如访问日志。如果所有电子邮件都是不同的,那么matthewh的解决方案也可以。

只是个人意见:我甚至不会费心用SQL来做这件事。只需将整个数据库拉入您最喜欢的脚本语言并在那里执行即可。这两种方式都会很慢,因为SQL根本不适合这种查询。请参见下文。无论我如何调整前缀长度或共享该前缀的行数,这些查询几乎总是花费不到一秒钟的时间。将整个数据库拉到什么位置?文本文件?那是个坏主意。可能会有数百万行,这只是我个人的看法:我甚至不会费心在SQL中这么做。只需将整个数据库拉入您最喜欢的脚本语言并在那里执行即可。这两种方式都会很慢,因为SQL根本不适合这种查询。请参见下文。无论我如何调整前缀长度或共享该前缀的行数,这些查询几乎总是花费不到一秒钟的时间。将整个数据库拉到什么位置?文本文件?那是个坏主意。可能会有数百万排。谢谢。正是我需要的。对于其他做这件事的人来说,我发现在做这件事的时候,我需要调整的参数比我预期的要高得多,因为我有多个合法用户使用像abraham****@gmail.com这样的电子邮件。正是我需要的。对于其他做这件事的人来说,我发现在做这件事的时候,我需要调整的参数比我预期的要高得多,因为我有多个合法用户使用像abraham****@gmail.com这样的电子邮件。有些令人惊讶的是,对于我有30K行的用户表,所有这些查询只花了不到一秒钟的时间。。。无论我如何调整子串长度或计数,这些都不应影响到任何显著程度;问题在于行的数量,以及在计算字段(如SUBSTR result)上分组不能使用索引的事实;因此,需要检查每一行。如果您需要此解决方案来扩大规模,那么最好将子字符串放在触发器维护的新列中,并为该列编制索引。有点令人惊讶的是,对于我的用户表(包含30K行),所有这些查询只需不到一秒钟的时间。。。无论我如何调整子串长度或计数,这些都不应影响到任何显著程度;问题在于行的数量,以及在计算字段(如SUBSTR result)上分组不能使用索引的事实;因此,需要检查每一行。如果您需要此解决方案来扩大规模,最好将子字符串放在由触发器维护的新列中,并为该列编制索引。