WITH RECURSIVE
cte1 AS
(
SELECT 1 num
UNION ALL
SELECT num + 1
FROM cte1
WHERE num < ( SELECT MAX(LENGTH(path) - LENGTH(REPLACE(path, '/', '')))
FROM mdl_course_categories )
),
cte2 AS
(
SELECT cte1.num,
cat.*,
SUBSTRING_INDEX(SUBSTRING_INDEX(cat.path, '/', cte1.num+1), '/', -1) onechar
FROM cte1, mdl_course_categories cat
WHERE cte1.num <= (LENGTH(path) - LENGTH(REPLACE(cat.path, '/', '')))
),
cte3 AS
(
SELECT cte2.*, cat.name onecharname
FROM cte2, mdl_course_categories cat
WHERE cte2.onechar = cat.id
)
SELECT id, name, parent, depth, path, GROUP_CONCAT(onecharname ORDER BY num SEPARATOR ' - ') breadcrumb
FROM cte3
GROUP BY id, name, parent, depth, path;
скрипка
Конечно, его можно сжать, но я думаю, что вы можете сделать это самостоятельно.
По запросу @ Shadow Я также даю простое решение
SELECT t1.id,
t1.name,
t1.parent,
t1.depth,
t1.path,
GROUP_CONCAT(t2.name ORDER BY LOCATE(CONCAT('/', t2.id, '/'), CONCAT(t1.path, '/')) SEPARATOR ' - ') breadcrumb
FROM mdl_course_categories t1,
mdl_course_categories t2
WHERE LOCATE(CONCAT('/', t2.id, '/'), CONCAT(t1.path, '/'))
GROUP BY t1.id,
t1.name,
t1.parent,
t1.depth,
t1.path;
PS. Помните, 1-й - O(N*AVG(M))
, тогда как 2-й - O(N*N)
- где N
- количество записей, а M
- глубина дерева.