该查询通过迭代表t_list
(最后一行)来工作。对于该表中的每一行,SELECT
子句中的子查询重新查询该表,搜索当前行的子行(WHERE parent = _parent
-- 但是_parent
是 的别名@r
)。在每次迭代中,孩子的id
被分配给@r
变量。
要添加边界,这种变化应该可以解决问题:
SELECT * FROM (
SELECT
@r AS _parent,
@r := (
SELECT id
FROM t_list
WHERE
( @c = 0 AND _parent IS NULL AND parent IS NULL ) -- special case if the first item is the root
OR (parent = _parent)
) AS id,
@c := @c + 1 AS rank
FROM (
SELECT @c := 0, @r := parent FROM t_list WHERE id = @start
) AS ini,
(
SELECT id FROM t_list LIMIT @limit
) AS lim
) AS tmp WHERE id IS NOT NULL;
将@start
和分别@limit
替换id
为第一个项目的 和要检索的最大项目数。请在这里测试。
使用 RDBMS 对这样的数据结构进行建模可能完全是个坏主意。为什么不只使用“索引”列?获取列表然后变得即时:
SELECT * FROM list ORDER BY index_column ASC;
也许您的列表应该经常更改,但是这样的查询应该相当快,除非列表变得非常大:
-- insert an element at position X
UPDATE list SET index_column = index_column +1 WHERE index_column > X ORDER BY index_column DESC;
INSERT INTO list VALUE (some_value, X);
-- delete an element at position X
DELETE FROM list WHERE index_column = X;
UPDATE list SET index_column = index_column -1 WHERE index_column > X ORDER BY index_column ASC;