如何在同一张表中查找父子节点?解决MariaDB子查询LIMIT报错问题
解决MariaDB递归查找父子节点的1235错误问题
这个问题我之前也碰到过!MariaDB确实有这个限制——不能在IN/ALL/ANY/SOME的子查询里搭配LIMIT使用,所以你原来的写法直接触发了1235错误。不过不用慌,我们可以用MariaDB 10.2及以上版本支持的**递归CTE(WITH RECURSIVE)**来完美解决树形结构的递归查询需求,不管是从根节点找子节点,还是从子节点向上找所有父节点直到根节点都没问题。
先解决你的核心错误
你原来的查询里用了WHERE id IN (SELECT id FROM categories WHERE parentid IS NULL LIMIT 1),这种IN子查询嵌套LIMIT的写法正是MariaDB禁止的。我们可以把LIMIT直接移到锚点查询里,结合递归CTE来实现需求。
场景1:从单个根节点(parentid IS NULL)出发,递归查询所有子节点
如果你原本想实现的是“取一个根节点,然后递归找出它的所有子节点”,可以用下面的语句:
WITH RECURSIVE category_tree AS ( -- 锚点查询:获取单个根节点(parentid为NULL的节点) SELECT id, name, parentid FROM categories WHERE parentid IS NULL LIMIT 1 UNION ALL -- 递归查询:关联父节点,获取所有子节点 SELECT c.id, c.name, c.parentid FROM categories c JOIN category_tree ct ON c.parentid = ct.id ) -- 最终只返回需要的id和name字段 SELECT id, name FROM category_tree;
场景2:从指定子节点出发,递归查询所有父节点直到根节点(parentid IS NULL)
如果你真正的需求是“递归查找某个节点的所有父节点,直到返回NULL(根节点)”,可以用下面的语句(把id = 10替换成你要查询的子节点ID即可):
WITH RECURSIVE parent_path AS ( -- 锚点查询:起始的子节点 SELECT id, name, parentid FROM categories WHERE id = 10 -- 替换为目标子节点ID UNION ALL -- 递归查询:向上关联父节点 SELECT c.id, c.name, c.parentid FROM categories c JOIN parent_path pp ON c.id = pp.parentid ) -- 最终返回所有父节点(包括起始节点本身) SELECT id, name FROM parent_path;
额外说明
- 先确认你的MariaDB版本:执行
SELECT VERSION();,如果版本低于10.2,递归CTE不被支持,建议升级版本;如果无法升级,只能用存储过程来实现递归,但这种方式代码繁琐且维护性差。 - 递归CTE是SQL标准的树形查询方式,比你原来用
UNION ALL拼接的写法更简洁、可读性更强,也更容易扩展。
内容的提问来源于stack exchange,提问作者reegan29
相关产品推荐
相关产品推荐

