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

Comment puis-je trouver tous les frères et sœurs de mon nœud et ses ancêtres dans une arborescence de catégories hiérarchique ?

Je ne suis pas sûr de suivre tout cela, mais on dirait que vous voulez tous les enfants immédiats de la catégorie 5.

Voici comment procéder :

SELECT child.*
FROM Category parent
  JOIN Category child 
    ON (child.lft BETWEEN parent.lft AND parent.rgt)
  LEFT JOIN Category intermediate 
    ON (intermediate.lft > parent.lft AND intermediate.rgt < parent.rgt
      AND child.lft > intermediate.lft AND child.rgt < intermediate.rgt)
WHERE intermediate.CategoryId IS NULL
  AND parent.CategoryId = ?;

modifier : D'accord, je comprends maintenant que la solution ci-dessus n'est qu'une partie de ce que vous voulez. Vous voulez :

  • Ancêtres directs des lecteurs de CD
  • "Oncles" des lecteurs de CD (frères et sœurs des ancêtres)
  • Frères et sœurs de lecteurs de CD
  • Enfants des lecteurs de CD

Laissez-moi travailler là-dessus pendant quelques minutes.

Voici ce que j'ai trouvé :

SELECT descendant.*,
  (current.lft BETWEEN descendant.lft AND descendant.rgt) AS is_selected,
  COUNT(DISTINCT c.CategoryId) AS depth
FROM Category current
JOIN Category selected 
  ON (current.lft BETWEEN selected.lft AND selected.rgt)
JOIN Category descendant 
  ON (descendant.lft BETWEEN selected.lft AND selected.rgt)
LEFT JOIN Category intermediate 
  ON (intermediate.lft > selected.lft AND intermediate.rgt < selected.rgt
    AND descendant.lft > intermediate.lft AND descendant.lft < intermediate.rgt)
JOIN Category c
  ON (descendant.lft BETWEEN c.lft AND c.rgt)
WHERE intermediate.CategoryId IS NULL
  AND current.CategoryId = ?
GROUP BY descendant.CategoryId
ORDER BY depth, descendant.name;
  • current est des lecteurs de CD
  • selected sont les ancêtres des lecteurs de CD (électronique, électronique portable, lecteurs de CD)
  • descendant est un enfant ou petit-enfant etc. de chaque selected ancêtre
  • intermediate est un descendant de chaque selected ancêtre qui est aussi un parent de descendant -- il ne doit y en avoir aucun, d'où le IS NULL restriction.
  • c est la chaîne d'ancêtres de descendant remonter vers le haut, afin de déterminer la profondeur.

Je viens de réaliser que ma solution renverrait également tous les descendants du current nœud. Ainsi, si vous visualisez actuellement des "appareils électroniques portables", la requête renverra ses enfants, mais elle renverra également le petit-enfant "flash", ce qui n'est peut-être pas ce que vous voulez.