问题描述
场景
在其历史的大部分时间里,我的公司在电子邮件地址中使用子域,主要是按州,但其他公司则使用部门子域。我们所拥有的一些示例包括:
mo.widgits.com
sd.widgits.com
va.widgits.com
nhq.widgits.com
gis.widgits.com
tech.widgits.com
...等等。
新范式
几年前,高层管理人员决定希望我们都成为一个幸福的家庭;作为这种文化调整的一部分,他们将每个人的电子邮件地址更改为单一域,格式为 firstname.lastname@widgits.com
。
目前的挑战
在我们的许多公司数据库中,我们发现混合使用旧格式和新格式的记录。例如,同一个人可能在员工系统中有 porky.pig@widgits.com
,在培训系统中有 porky.pig@in.widgits.com
。我需要在各种系统中匹配个人,而不管该系统中为他们使用哪种格式的电子邮件。
想要的匹配
porky.pig@in.widgits.com = porky.pig@widgits.com -> true
mary.poppins@widgits.com = mary.poppins@nhq.widgits.com -> true
bob.baker@widgits.com = bob.barker@gis.widgits.com -> false
如何做到这一点?
是否有正则表达式模式可以用来匹配电子邮件地址,而不管它们是哪种格式?或者我是否需要在尝试匹配子域之前手动提取子域?
解决方法
在我看来,您可以在比较之前从所有电子邮件地址中去除子域(即,仅比较电子邮件名称和域)。像这样:
SELECT *
FROM emails
WHERE REGEXP_REPLACE(email1,'^(.*@).*?([^.]+\.[^.]+)$','\1\2') =
REGEXP_REPLACE(email2,'\1\2');
Demo
数据:
WITH emails AS (
SELECT 'porky.pig@in.widgits.com' AS email1,'porky.pig@widgits.com' AS email2 UNION ALL
SELECT 'mary.poppins@widgits.com','mary.poppins@nhq.widgits.com' UNION ALL
SELECT 'bob.baker@widgits.com','bob.barker@gis.widgits.com'
)
这里是对使用的正则表达式模式的解释:
^ start of the email
(.*@) match email name including @ in \1
.*? consume content up,but not including
([^.]+\.[^.]+) final domain only (e.g. google.com)
$ end of the email
然后,我们替换为 \1\2
以有效删除任何子域组件。
这样的事情怎么样?
SELECT
*
FROM
(
SELECT
table1.email,table2.email,SPLIT_PART(table1.email,'@',1) AS table1_username,SPLIT_PART(table2.email,1) AS table2_username,2) AS table1_domain,2) AS table2_domain
FROM
table1 CROSS
JOIN table2
) S
WHERE
(
table1_username = table2_username
AND (
table1_domain like '%.' || table2_domain
OR table2_domain like '%.' || table1_domain
)
);