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česelected
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éhoselected
předkaintermediate
je potomkem každéhoselected
předek, který je také rodičemdescendant
-- žádná z nich nesmí být, protoIS NULL
omezení.c
je řetězec předků zdescendant
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.