MariaDB递归CTE中CONCAT未拼接字符串问题咨询
递归CTE中CONCAT未拼接路径的原因及解决办法
你的问题出在递归CTE的递归分支写法上,没有正确引用上一轮递归生成的路径字段进行累积拼接,导致始终使用初始的路径值,而非逐步拼接后的结果。
示例错误写法(可能和你的代码类似):
假设你的建表语句是:
CREATE TABLE graph ( src VARCHAR(10), dest VARCHAR(10) ); INSERT INTO graph VALUES ('a', 'b');
错误的递归CTE代码:
WITH RECURSIVE path AS ( SELECT src AS path, src AS node FROM graph WHERE src = 'a' UNION ALL -- 这里错误:直接使用固定字符串'a',而非上一轮的path字段 SELECT CONCAT('a', '->', g.dest), g.dest FROM path p JOIN graph g ON p.node = g.src ) SELECT * FROM path;
这段代码的递归分支里,CONCAT的第一个参数是固定的'a',而非上一轮递归得到的p.path,所以结果里的路径始终是'a',不会拼接成'a->b'。
正确写法:
修改递归分支,引用上一轮的path字段进行累积拼接:
WITH RECURSIVE path AS ( -- 锚点:起始节点,路径为自身 SELECT src AS path, src AS node FROM graph WHERE src = 'a' UNION ALL -- 递归部分:用上一轮的路径拼接当前目标节点 SELECT CONCAT(p.path, '->', g.dest), g.dest FROM path p JOIN graph g ON p.node = g.src ) SELECT * FROM path;
执行这段代码后,就能得到预期的结果:
| path | node |
|---|---|
| a | a |
| a->b | b |
关键注意点:
- 递归CTE的递归分支必须引用锚点或之前递归结果中的路径字段(比如
p.path),才能实现路径的累积拼接 - 确保锚点和递归分支返回的字段数量、数据类型一致,避免隐式转换导致的异常
- MariaDB 10.3.27完全支持递归CTE,版本不是问题
内容的提问来源于stack exchange,提问作者user2926204
相关产品推荐
相关产品推荐

