該查詢的工作原理是遍歷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
,以及項目的最大數量來檢索,分別。請test it here。
用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;
請您發表您的設置在http://sqlfiddle.com或只准備數據庫轉儲? – Quassnoi