Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como posso encontrar todos os irmãos do meu nó e seus âncoras em uma árvore de categorias hierárquica?


Não tenho certeza se entendi tudo isso, mas parece que você quer todos os filhos imediatos da categoria 5.

Aqui está uma maneira de fazer isso:
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: Ok, entendi agora que a solução acima é apenas uma parte do que você deseja. Você quer:
  • Ancestrais diretos dos tocadores de CD
  • "Tios" de CD players (irmãos de ancestrais)
  • Irmãos de tocadores de CD
  • Filhos de CD players

Deixe-me trabalhar nisso por alguns minutos.

Aqui está o que eu inventei:
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 é leitores de CD
  • selected é ancestral dos tocadores de CD (eletrônicos, eletrônicos portáteis, tocadores de CD)
  • descendant é qualquer filho ou neto etc. de cada selected ancestral
  • intermediate é descendente de cada selected ancestral que também é pai de descendant -- não deve haver nenhum deles, portanto, IS NULL restrição.
  • c é a cadeia de ancestrais de descendant volte para o topo, para determinar a profundidade.

Acabei de perceber que minha solução também retornaria todos os descendentes do current nó. Portanto, se você estivesse visualizando "eletrônicos portáteis", a consulta retornaria seus filhos, mas também retornaria o "flash" do neto, que pode não ser o que você deseja.