sql >> Databáze >  >> RDS >> Mysql

Jak mohu najít všechny sourozence mého uzlu a jeho předchůdců v hierarchickém stromu kategorií?

Nejsem si jistý, jestli to všechno dodržuji, ale zní to, jako byste chtěli všechny bezprostřední děti kategorie 5.

Zde je způsob, jak to udělat:

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

upravit: Dobře, nyní chápu, že výše uvedené řešení je pouze částí toho, co chcete. Chcete:

  • Přímí předkové CD přehrávačů
  • "Strýcové" CD přehrávačů (sourozenci předků)
  • Sourozenci CD přehrávačů
  • Děti přehrávačů CD

Nech mě na tom pár minut pracovat.

Tady je to, na co jsem přišel:

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 jsou CD přehrávače
  • selected je předky CD přehrávačů (elektronika, přenosná elektronika, CD přehrávače)
  • descendant je jakékoli dítě nebo vnuk atd. každého selected předka
  • intermediate je potomkem každého selected předek, který je také rodičem descendant -- žádná z nich nesmí být, proto IS NULL omezení.
  • c je řetězec předků z descendant zpět nahoru, pro účely určení hloubky.

Právě jsem si uvědomil, že moje řešení by také vrátilo všechny potomky current uzel. Takže pokud jste právě prohlíželi „přenosnou elektroniku“, dotaz by vrátil své potomky, ale také by vrátil vnuk „flash“, což nemusí být to, co chcete.



  1. Přehled možností JSON v PostgreSQL

  2. Dotaz SQL pro 7denní klouzavý průměr v SQL Server

  3. Trigram Wildcard String Search v SQL Server

  4. Spouštěč aktualizace SQL pouze při změně sloupce