Mysql
 sql >> Base de données >  >> RDS >> Mysql

requête mysql pour la liste chaînée

La requête fonctionne en itérant sur la t_list tableau (la dernière ligne). Pour chaque ligne de ce tableau, la sous-requête dans le SELECT la clause réinterroge la table, en recherchant l'enfant de la ligne actuelle (WHERE parent = _parent -- mais _parent est un alias pour @r ). A chaque itération, l'id de l'enfant est affecté au @r variables.

Pour ajouter des limites, cette variante devrait faire l'affaire :

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;

Remplacez @start et @limit avec l'id du premier élément et le nombre maximal d'éléments à récupérer, respectivement. Veuillez tester ici .

Modéliser une telle structure de données avec un SGBDR est probablement une mauvaise idée. Pourquoi ne pas simplement utiliser une colonne "index" ? L'obtention de la liste devient alors instantanée :

SELECT * FROM list ORDER BY index_column ASC;

Peut-être que votre liste est censée changer fréquemment, mais les requêtes comme celle-ci devraient être assez rapides à moins que la liste ne devienne très longue :

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