Question

Votre configuration de type de hiérarchie d'ensembles imbriqués est définie avec les colonnes suivantes:

nom de la table:

myset

colonnes:

id, name, lft, rgt

Quelqu'un connaît-il une requête pour déterminer le parent d'un nœud?

J'ai lu quelques endroits où il est pratique d'avoir également une colonne parent_id dans votre tableau pour garder une trace de cela, mais cela semble redondant et il semble que cela pourrait ne plus être synchronisé avec l'imbrication définir si une requête a été mal exécutée lors de l'ajout / la suppression / du déplacement d'un élément dans l'ensemble.

Était-ce utile?

La solution

Regardez cette question . C'est semblable au vôtre. J'ai posté une requête dont vous pourriez avoir besoin.

SELECT title, (SELECT TOP 1 title 
           FROM tree t2 
           WHERE t2.lft < t1.lft AND t2.rgt > t1.rgt    
           ORDER BY t2.rgt-t1.rgt ASC) AS parent
FROM tree t1
ORDER BY rgt-lft DESC

J'espère qu'il y a ce dont vous avez besoin.

Pour le tableau suivant:

+-------------+----------------------+-----+-----+
| category_id | name                 | lft | rgt |
+-------------+----------------------+-----+-----+
|           1 | ELECTRONICS          |   1 |  20 |
|           2 | TELEVISIONS          |   2 |   9 |
|           3 | TUBE                 |   3 |   4 |
|           4 | LCD                  |   5 |   6 |
|           5 | PLASMA               |   7 |   8 |
|           6 | PORTABLE ELECTRONICS |  10 |  19 |
|           7 | MP3 PLAYERS          |  11 |  14 |
|           8 | FLASH                |  12 |  13 |
|           9 | CD PLAYERS           |  15 |  16 |
|          10 | 2 WAY RADIOS         |  17 |  18 |

il produit le résultat:

title                | parent
----------------------------------------------
ELECTRONICS          | NULL
PORTABLE ELECTRONICS | ELECTRONICS
TELEVISIONS          | ELECTRONICS
MP3 PLAYERS          | PORTABLE ELECTRONICS
FLASH                | MP3 PLAYERS
CD PLAYERS           | PORTABLE ELECTRONICS
2 WAY RADIOS         | PORTABLE ELECTRONICS
TUBE                 | TELEVISIONS
LCD                  | TELEVISIONS
PLASMA               | TELEVISIONS

Autres conseils

TOP est une commande MSSQL, utilisez LIMIT for MySQL:

SELECT title, (SELECT title 
       FROM tree t2 
       WHERE t2.lft < t1.lft AND t2.rgt > t1.rgt    
       ORDER BY t2.rgt-t1.rgt ASC
       LIMIT 1) 
AS parent FROM tree t1 
ORDER BY (rgt-lft) DESC

Devrait faire l'affaire.

juste pour ajouter à ces réponses qui m'a beaucoup aidé,

je devais trouver le parent immédiat d'un nœud, ainsi que le parent de niveau supérieur d'une chaîne de nœuds dans certains cas,

J'ai utilisé les éléments suivants comme base pour obtenir les éléments dans l'ordre parent-parent

SELECT parent.*  FROM
        nested_set node,
        nested_set parent
        WHERE (
            node.set_left BETWEEN parent.set_left AND parent.set_right          
        )
        AND node.set_id={CHILD_NODE_ID_HERE}
        ORDER BY parent.set_right - parent.set_left
        #LIMIT 1,1

il s’agit alors d’ajouter le LIMIT 1,1 pour ne capturer que la deuxième ligne qui serait le parent immédiat

il convient également de noter qu'avec la requête ci-dessus, si le nœud lui-même est le parent de niveau supérieur, il ne disposerait donc pas d'un parent immédiat . Par conséquent, avec le >= <=, il devrait renvoyer jeu de résultats vide

pour obtenir le parent de niveau supérieur, j'ai inversé la clause order by, inclus une vérification si le nœud lui-même est le parent supérieur et limité le résultat à la première ligne

SELECT parent.* AS top_level_right FROM
        nested_set node,
        nested_set parent
        WHERE (
            node.set_left >= parent.set_left 
            AND node.set_left <= parent.set_right
        )
        AND node.set_id={CHILD_NODE_ID_HERE}
        ORDER BY parent.set_left - parent.set_right
        LIMIT 1

dans la dernière requête, j'ai utilisé <=> des opérateurs pour que la plage sélectionnée englobe le nœud enfant s'il s'avère également être le parent de niveau supérieur

J'ai eu un problème avec la requête de Lucasz. Ma version de mysql ne comprenait pas la commande TOP. J'ai dû utiliser LIMIT à la place. Voici le code révisé.

SELECT 
   `id`, 
   (SELECT 
      `id`
    FROM 
       `[*** YOUR TABLE ***]` AS `t2` 
    WHERE 
       `t2`.`left_id`  < `t1`.`left_id`AND 
       `t2`.`right_id` > `t1`.`right_id`
    ORDER BY 
       `t2`.`right_id`-`t1`.`right_id`ASC 
    LIMIT 
       1) AS `parent`
FROM 
    `[*** YOUR TABLE ***]` AS `t1`
WHERE 
    `t1`.`id` = [*** ID OF THE NODE WHOS PARENT YOU WISH TO LOOKUP ***]
ORDER BY 
    `right_id`-`left_id` DESC

Évidemment, modifiez les éléments dans les [] en fonction de vos besoins. Supprimez également les []. Cette requête ne renvoie qu'une ligne. Comme si ...

id  parent
7   3
select * from myset
  where lft < :lftOfCurrent and rgt > :lftOfCurrent
  order lft desc
  limit 1

Vous pouvez utiliser un maximum plutôt que l'ordre / limite et vous aurez peut-être besoin d'un autre mot clé pour limiter les résultats à une ligne, en fonction de votre base de données. Entre plutôt que & Lt; et > fonctionnerait si votre base de données renvoie l'ensemble exclusif, ce que MySQL ne fait pas.

SELECT parent.name 
FROM myset AS node, myset AS parent 
WHERE parent.lft < node.lft 
AND parent.rgt > node.rgt 
AND node.id = {YOUR CATEGORY ID} 
ORDER BY ( parent.rgt - parent.lft ) ASC LIMIT 1;

Tous les ancêtres sont renvoyés par

SELECT id FROM thetable
WHERE x BETWEEN lft and rgt;

Le parent direct est donc l'ancêtre avec la plus petite différence entre lft et rgt.

SELECT id FROM thetable
WHERE x BETWEEN lft and rgt
ORDER BY (rgt-lft)
LIMIT 1

Le code de spankmaster79 n'était pas complètement faux. J'ai modifié son code et cela a fonctionné.

SELECT parent . * FROM Nested_Category AS node, Nested_Category AS parent 
enter code hereWHERE node.leftSide
BETWEEN parent.leftSide
AND parent.rightSide
AND node.id ='Enter the Node ID'
ORDER BY (
parent.rightSide - parent.leftSide
)
LIMIT 1 , 1
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top