按外键递归深度对MySQL查询结果进行排序的实现方案
按外键递归深度对MySQL查询结果排序
嘿,要实现按递归深度从深到浅排序MySQL的查询结果,用**递归CTE(公共表表达式)**就能轻松搞定!先结合你的表结构和需求,一步步来:
先明确你的数据结构
假设你的表名为your_table,结构和数据如下:
CREATE TABLE your_table ( id INT PRIMARY KEY, parent INT NULL, FOREIGN KEY (parent) REFERENCES your_table(id) ); INSERT INTO your_table VALUES (1, 4), (2, 1), (3, NULL), (4, NULL), (5, 2), (6, 3);
我们的目标是让递归层级最深的节点排在最前面,比如节点5的递归路径是5→2→1→4,共3层,所以它要排第一。
核心解决方案:递归CTE计算深度+排序
直接上可运行的SQL,我会给你解释每部分的作用:
WITH RECURSIVE node_depth AS ( -- 第一步:先抓所有顶层节点(没有父节点的),它们的深度设为0 SELECT id, parent, 0 AS depth FROM your_table WHERE parent IS NULL UNION ALL -- 第二步:递归遍历子节点,每个子节点的深度=父节点深度+1 SELECT t.id, t.parent, nd.depth + 1 AS depth FROM your_table t JOIN node_depth nd ON t.parent = nd.id ) -- 第三步:按深度倒序排序,深度相同的话可以按id顺排保证结果稳定 SELECT id, parent, -- 生成你要的排序原因说明 CASE WHEN depth = 0 THEN CONCAT(id, '没有父节点,共0层递归') WHEN depth = 1 THEN CONCAT(id, '的父级是', parent, ',共1层递归') ELSE CONCAT(id, '的父级是', parent, ',共', depth, '层递归') END AS 排序原因 FROM node_depth ORDER BY depth DESC, id ASC;
执行后的结果
运行上面的SQL,会得到完全符合你期望的排序:
+----+--------+------------------------------------------+ | id | parent | 排序原因 | +----+--------+------------------------------------------+ | 5 | 2 | 5的父级是2,共3层递归 | | 2 | 1 | 2的父级是1,共2层递归 | | 1 | 4 | 1的父级是4,共1层递归 | | 6 | 3 | 6的父级是3,共1层递归 | | 3 | NULL | 3没有父节点,共0层递归 | | 4 | NULL | 4没有父节点,共0层递归 | +----+--------+------------------------------------------+
关键逻辑拆解
- 锚点查询:先定位所有顶层节点(
parent IS NULL),这些节点没有父节点,所以深度为0。 - 递归查询:通过JOIN关联子节点和它的父节点,把父节点的深度加1作为子节点的深度,这样就能一层层遍历整个树形结构,算出每个节点的递归层级。
- 排序规则:用
ORDER BY depth DESC实现从深到浅的排序,后面加id ASC是为了在深度相同的时候,让结果有稳定的排序顺序,你也可以换成其他字段。
内容的提问来源于stack exchange,提问作者Simon Baars




