Mysql
 sql >> Database >  >> RDS >> Mysql

Come posso trovare tutti i fratelli del mio nodo e dei suoi antenati in un albero di categorie gerarchico?

Non sono sicuro di seguire tutto questo, ma sembra che tu voglia tutti i figli immediati della categoria 5.

Ecco un modo per farlo:

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

modifica: Ok, ora capisco che la soluzione sopra è solo una parte di ciò che desideri. Vuoi:

  • Progenitori diretti dei lettori CD
  • "Zii" di lettori CD (fratelli di antenati)
  • Fratelli dei lettori CD
  • Figli di lettori CD

Fammi lavorare su questo per qualche minuto.

Ecco cosa mi è venuto in mente:

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 sono lettori CD
  • selected è l'antenato dei lettori CD (elettronica, elettronica portatile, lettori CD)
  • descendant è qualsiasi figlio o nipote ecc. di ogni selected antenato
  • intermediate è un discendente di ogni selected antenato che è anche un genitore di descendant -- non ci deve essere nessuno di questi, quindi IS NULL restrizione.
  • c è la catena di antenati da descendant tornare in alto, ai fini della determinazione della profondità.

Mi sono appena reso conto che la mia soluzione avrebbe restituito anche tutti i discendenti del current nodo. Quindi, se al momento stavi visualizzando "elettronica portatile", la query restituirebbe i suoi figli, ma restituirebbe anche il "flash" del nipote che potrebbe non essere quello che desideri.