Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie kann ich in einem hierarchischen Kategoriebaum alle Geschwister meines Knotens und seiner Vorläufer finden?

Ich bin mir nicht sicher, ob ich dem alles folge, aber es hört sich so an, als wollten Sie alle unmittelbar untergeordneten Elemente der Kategorie 5.

Hier ist eine Möglichkeit, das zu tun:

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

Bearbeiten: Okay, ich verstehe jetzt, dass die obige Lösung nur ein Teil dessen ist, was Sie wollen. Sie wollen:

  • Direkte Vorfahren von CD-Playern
  • "Onkel" von CD-Playern (Geschwister von Vorfahren)
  • Geschwister von CD-Playern
  • Kinder von CD-Playern

Lassen Sie mich ein paar Minuten daran arbeiten.

Folgendes habe ich mir ausgedacht:

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 ist CD-Player
  • selected ist Vorfahren von CD-Playern (Elektronik, tragbare Elektronik, CD-Player)
  • descendant ist ein beliebiges Kind oder Enkelkind usw. jedes selected Vorfahre
  • intermediate ist ein Nachkomme jedes selected Vorfahr, der auch ein Elternteil von descendant ist -- es darf keines davon geben, daher IS NULL Einschränkung.
  • c ist die Kette der Vorfahren von descendant zurück nach oben, um die Tiefe zu bestimmen.

Ich habe gerade festgestellt, dass meine Lösung auch alle Nachkommen des current zurückgeben würde Knoten. Wenn Sie also gerade „tragbare Elektronik“ anzeigen, würde die Abfrage ihre Kinder zurückgeben, aber sie würde auch das Enkelkind „flash“ zurückgeben, was möglicherweise nicht das ist, was Sie wollen.