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

MySQL递归查询筛选含匹配节点的树形分支

MySQL树形结构提取含匹配节点的完整分支解决方案

需求说明

在MySQL中,存在具有父子树形结构的表,每个节点包含多个属性。需要提取所有至少有一个节点属性匹配查询条件的完整分支,即从根节点到匹配节点的整条路径上的所有节点。

示例数据

------------------------
|id|parent |description |
------------------------
| 1|NULL   |First root  |
| 2|NULL   |Second root |
| 3|1      |First child |
| 4|1      |Second child|
| 5|1      |Third child |
| 6|2      |First child |
| 7|2      |Second child|
| 8|6      |First child |
| 9|6      |Second child|
|10|6      |Third child |
|11|5      |First child |

查询条件

WHERE description LIKE "Third%"

期望返回结果

------------------------
|id|parent |description |
------------------------
| 1|NULL   |First root  |
| 2|NULL   |Second root |
| 5|1      |Third child |
| 6|2      |First child |
|10|6      |Third child |

现有问题语句

原递归查询仅从根节点向下筛选匹配的子节点,无法保留根节点到匹配节点之间的非匹配节点,导致结果不完整:

WITH RECURSIVE tmp (id,parent,description,parent_name, parent_description) AS (
   SELECT id,parent,description,NULL,NULL 
   FROM table 
   WHERE parent IS NULL
UNION ALL
   SELECT table.*, tmp.parent,tmp.description 
   FROM tmp 
   JOIN table ON table.parent=tmp.id 
   WHERE table.description LIKE "Third%" 
)
SELECT * FROM tmp;

可行解决方案

正确的思路是从匹配节点向上递归追溯所有祖先节点,确保整条路径的节点都被包含,具体SQL如下:

WITH RECURSIVE matched_paths AS (
    -- 第一步:定位所有符合查询条件的节点
    SELECT id, parent, description
    FROM your_table
    WHERE description LIKE 'Third%'
    UNION ALL
    -- 第二步:递归向上查找每个匹配节点的所有祖先(直到根节点)
    SELECT t.id, t.parent, t.description
    FROM your_table t
    JOIN matched_paths mp ON t.id = mp.parent
)
-- 去重并排序,确保结果结构清晰
SELECT DISTINCT id, parent, description
FROM matched_paths
ORDER BY parent IS NULL DESC, parent, id;

逻辑说明

  1. 递归CTE的第一部分先找出所有满足条件的节点;
  2. 第二部分通过关联父节点,不断向上递归获取每个匹配节点的所有祖先,包括根节点;
  3. 使用DISTINCT去重(避免多个子节点共享祖先时重复输出),最后排序让根节点优先展示,结果层级更直观。

内容的提问来源于stack exchange,提问作者Alessandro Magri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:45:41