sql >> Base de Datos >  >> RDS >> Mysql

¿Cómo puedo encontrar todos los hermanos de mi nodo y sus antecesores en un árbol de categorías jerárquicas?

No estoy seguro de seguir todo eso, pero parece que quieres que todos los niños inmediatos de la categoría 5.

Esta es una forma de hacerlo:

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

editar: Bien, ahora entiendo que la solución anterior es solo una parte de lo que desea. Quieres:

  • Ancestros directos de los reproductores de CD
  • "Tíos" de reproductores de CD (hermanos de antepasados)
  • Hermanos de los reproductores de CD
  • Hijos de reproductores de CD

Déjame trabajar en eso por unos minutos.

Esto es lo que se me ocurrió:

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 son reproductores de CD
  • selected son los ancestros de los reproductores de CD (electrónicos, electrónicos portátiles, reproductores de CD)
  • descendant es cualquier hijo o nieto, etc. de cada selected antepasado
  • intermediate es un descendiente de cada selected antepasado que también es padre de descendant -- no debe haber ninguno de estos, por lo tanto, IS NULL restricción.
  • c es la cadena de antepasados ​​de descendant volver a la parte superior, con el fin de determinar la profundidad.

Me acabo de dar cuenta de que mi solución también devolvería todos los descendientes del current nodo. Entonces, si actualmente estuviera viendo "electrónica portátil", la consulta devolvería sus hijos, pero también devolvería el nieto "flash", que puede no ser lo que desea.