You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL递归查询:从两张表中获取用户所有关联的邮箱地址

问题描述

我有两张表,第一张名为 emails,存储了所有同事的主邮箱信息,表结构及数据如下:

email
saramaia@email.com
miguelferreira@email.com
joaosilva@email.com
joanamaia@email.com

第二张表名为 aliases,存储了同事使用的所有别名邮箱的映射关系,表结构及数据如下:

alias1alias2
joanamaia@email.commaiajoana@email.com
maiajoana@email.commaia@email.com
miguelferreira@email.commiguel@email.com
maia@email.comjoana@email.com
joanamaia@email.comjomaia@email.com
joana@email.comjmaia@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 18:03:01