Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL-Abfrage für verkettete Liste

Die Abfrage funktioniert, indem sie über die t_list iteriert Tabelle (die letzte Zeile). Für jede Zeile in dieser Tabelle die Unterabfrage im SELECT -Klausel fragt die Tabelle erneut ab und sucht nach dem untergeordneten Element der aktuellen Zeile (WHERE parent = _parent -- aber _parent ist ein Alias ​​für @r ). Bei jeder Iteration die id des Kindes wird dem @r zugewiesen Variable.

Um Grenzen hinzuzufügen, sollte diese Variante ausreichen:

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;

Ersetzen Sie @start und @limit mit der id des ersten Elements bzw. die maximale Anzahl der abzurufenden Elemente. Bitte hier testen .

Die Modellierung einer solchen Datenstruktur mit einem RDBMS ist wahrscheinlich insgesamt eine schlechte Idee. Warum nicht einfach eine "Index"-Spalte verwenden? Das Abrufen der Liste erfolgt dann sofort:

SELECT * FROM list ORDER BY index_column ASC;

Vielleicht soll sich Ihre Liste häufig ändern, aber Abfragen wie diese sollten ziemlich schnell sein, es sei denn, die Liste wird sehr groß:

-- 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;