Frågan fungerar genom att iterera över t_list
tabell (sista raden). För varje rad i den här tabellen, underfrågan i SELECT
klausul frågar om tabellen och söker efter den aktuella radens underordnade (WHERE parent = _parent
-- men _parent
är ett alias för @r
). Vid varje iteration, barnets id
är tilldelad @r
variabel.
För att lägga till gränser bör den här varianten göra susen:
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;
Ersätt @start
och @limit
med id
av det första föremålet respektive det maximala antalet föremål att hämta. Vänligen testa det här
.
Att modellera en sådan datastruktur med ett RDBMS är förmodligen en dålig idé helt och hållet. Varför inte bara använda en "index" kolumn? Att hämta listan blir då omedelbart:
SELECT * FROM list ORDER BY index_column ASC;
Kanske är det meningen att din lista ska ändras ofta, men sådana här frågor bör vara ganska snabba om inte listan blir riktigt stor:
-- 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;