通过使用另一个连接,您可以应用与单个id相同的逻辑,因此基本上会多次重复该计算。由于不能再使用固定的开始值,我对条件进行编码,以重新初始化交叉连接中的变量(“reset\u r”)。
请尝试以下操作:
SELECT t1.id, GROUP_CONCAT(t1.r ORDER BY t1.lvl DESC) AS parents
FROM (
SELECT
t0.r_init AS id,
@r := IF(t0.reset_r = 1, t0.r_init,
(select parent_id from menu where id = @r)) AS r,
@l := IF(t0.reset_r = 1, 1, @l + 1) AS lvl
FROM
(SELECT m0.id as counter, m1.id AS r_init,
((SELECT min(id) FROM menu) = m0.id) AS reset_r
FROM menu m0, menu m1
WHERE m1.id IN (25, 31, 23)
) t0
ORDER BY t0.r_init, t0.counter
) t1
WHERE t1.r <> 0
-- or instead of "where":
-- JOIN menu t2 ON t2.id = t1.r;
GROUP BY t1.id;
对于大型表,您应该限制
p
different data model
. 此外,尽管您的表结构可能是一个示例,但您显然应该使用主键(否则父项和重置条件定义不明确)和相同的数据类型
parent_id
和
id
使现代化
:MySQL 5.6查询的一个版本(应该可以在
sql-fiddle
SELECT t2.id, GROUP_CONCAT(t2.r ORDER BY t2.lvl DESC)
FROM (
SELECT id, r, lvl
FROM (
SELECT
t0.r_init AS id,
@r := IF(t0.reset_r = 1, t0.r_init,
(select parent_id from menu where id = @r)) AS r,
@l := IF(t0.reset_r = 1, 1, @l + 1) AS lvl
FROM
(SELECT m0.id as counter, m1.id AS r_init,
((SELECT min(id) FROM menu) = m0.id) AS reset_r
FROM menu m0, menu m1
WHERE m1.id IN (25, 31, 23)
ORDER BY r_init, counter
) t0
ORDER BY t0.r_init, t0.counter
) t1
WHERE r <> 0
) t2
GROUP BY t2.id;