MySQL递归查询:从两张表中获取用户所有关联的邮箱地址
问题描述
我有两张表,第一张名为 emails,存储了所有同事的主邮箱信息,表结构及数据如下:
| saramaia@email.com |
| miguelferreira@email.com |
| joaosilva@email.com |
| joanamaia@email.com |
第二张表名为 aliases,存储了同事使用的所有别名邮箱的映射关系,表结构及数据如下:
| alias1 | alias2 |
|---|---|
| joanamaia@email.com | maiajoana@email.com |
| maiajoana@email.com | maia@email.com |
| miguelferreira@email.com | miguel@email.com |
| maia@email.com | joana@email.com |
| joanamaia@email.com | jomaia@email.com |
| joana@email.com | jmaia@email.com |
我需要实现的效果是:给定任意一个用户的邮箱(无论主邮箱还是别名邮箱),返回该用户正在使用的所有邮箱地址列表,包含主邮箱以及所有通过别名关联的链式邮箱。
以用户 joanamaia@email.com 为例,无论使用 WHERE email='joanamaia@email.com' 还是 WHERE email='jmaia@email.com' 作为查询条件,都要返回以下完整的关联邮箱列表:
| emails |
|---|
| joanamaia@email.com |
| jomaia@email.com |
| maiajoana@email.com |
| maia@email.com |
| joana@email.com |
| jmaia@email.com |
实现方案
这类链式关联的查询本质是图的连通节点遍历问题,使用**递归公用表表达式(递归CTE)**可以简洁实现,MySQL 8.0+、PostgreSQL、SQL Server等主流数据库均支持该语法:
WITH RECURSIVE related_emails AS ( -- 锚点成员:输入待查询的目标邮箱 SELECT '替换为你要查询的邮箱地址' AS email UNION -- 递归成员:遍历别名映射表,找到所有关联的邮箱 SELECT IF(ae.email = a.alias1, a.alias2, a.alias1) AS email FROM related_emails ae INNER JOIN aliases a ON ae.email = a.alias1 OR ae.email = a.alias2 -- 排除已收录的邮箱,避免循环递归 WHERE IF(ae.email = a.alias1, a.alias2, a.alias1) NOT IN (SELECT email FROM related_emails) ) -- 输出所有关联邮箱 SELECT email AS emails FROM related_emails;
语法兼容说明
如果使用的是不支持递归CTE的低版本数据库(如MySQL 5.x),可以通过存储过程循环查询别名表、逐步收集关联邮箱的方式实现相同逻辑。
内容的提问来源于stack exchange,提问作者Tiago M
相关产品推荐
相关产品推荐

