Wie kann ich alle Blattknoten in einer SQL-Hierarchie unter einem bestimmten Knoten wählen?

StackOverflow https://stackoverflow.com/questions/378608

  •  22-08-2019
  •  | 
  •  

Frage

Ich habe eine Reihe von Daten, die Modelle eine Hierarchie von Kategorien. Eine Wurzel enthält eine Reihe von Top-Level-Kategorien. Jede Kategorie der obersten Ebene enthält eine Reihe von Unterkategorien.

Jede Unterkategorie verfügt über eine Reihe von Organisationen. Eine gegebene Organisation kann in mehrere Unterkategorien erscheinen.

Die Blattknoten dieser Hierarchie sind Organisationen. Eine Organisation kann in mehreren Untergruppen erscheint möglicherweise.

Die Daten in drei SQL-Tabellen gespeichert ist:

organizations
organization_id organization_name
1               Org A
2               Org B
3               Org C
4               Org D
5               Org E
6               Org F

categories
category_id parent_id category_name
0           NULL      Top Level Category
1           0         First Category
2           0         Second Category
3           1         Sub Category A
4           1         Sub Category B
5           1         Sub Category C
6           2         Sub Category D

organizations_categories -- Maps organizations to sub_categories
organization_id category_id
1               3
2               3
2               6
3               4
4               4
5               4
6               5
6               4
7               6
8               6

Ich möchte in der Lage sein, eine Liste aller einzigartigen Organisationen unter einer bestimmten Kategorie oder Unterkategorie auszuwählen.

So wie ich es jetzt täte, beinhaltet Bezifferung erste heraus, welche Unterkategorien angefordert wurde und dann durch jeden sub_category in Code Looping und Durchführung eine Auswahl alle Organisationen zu dieser Kategorie zugeordnet zu bekommen. Die Ergebnisse jeder Auswahl werden einem Array angehängt. Dieses Array enthält Duplikate, wenn eine Organisation in mehrere Unterkategorien angezeigt wird.

Ich würde gerne diese Flickschusterei mit einer Abfrage zu ersetzen, die effizient eine Liste von verschiedenen Organisationen gegeben eine ID von einem der Kategorien in der Hierarchie auswählen können.

Ich entwickelnde diese Lösung PHP und MySQL.

Vielen Dank für Ihre Zeit und Anregungen.

War es hilfreich?

Lösung

Unter der Annahme, dass die Hierarchie ist immer genau drei Ebene tief:

SELECT DISTINCT
     O.organization_id,
     O.organization_name
FROM
     Categories CAT
INNER JOIN Categories SUB ON
     SUB.parent_id = CAT.category_id
INNER JOIN Category_Organizations CO ON
     CO.category_id = SUB.category_id
INNER JOIN Organizations O ON
     O.organization_id = CO.organization_id
WHERE
     CAT.category_id = @category_id

Sie können das um eine Stufe ändern, damit Sie eine Unterkategorie-ID zu übergeben. Wenn Sie nicht an der Zeit wissen, ob Sie eine Kategorie-ID oder eine Unterkategorie-ID haben, dann können Sie wie folgt vor:

SELECT DISTINCT
     O.organization_id,
     O.organization_name
FROM
     Categories CAT
LEFT OUTER JOIN Categories SUB ON
     SUB.parent_id = CAT.category_id
INNER JOIN Category_Organizations CO ON
     CO.category_id IN (CAT.category_id, SUB.category_id)
INNER JOIN Organizations O ON
     O.organization_id = CO.organization_id
WHERE
     CAT.category_id = @category_id

Wenn Ihre Hierarchie kann eine unbekannte Anzahl von Ebenen (oder denken Sie, es könnte in der Zukunft) dann check out Joe Celko der Bäume und Hierarchien in SQL für Smarties für alternative Möglichkeiten, um eine Hierarchie zu modellieren. Es ist wahrscheinlich eine gute Idee, das zu tun, trotzdem.

Andere Tipps

Nicht sicher, ob Ihr Datenmodell es ermöglichen wird, aber Sie können einen einzelnen Indexspalte und einen Binary Tree verwenden leicht diese Informationen speichern in einem einzigen ‚OrganizationTree‘ Tisch. Auch hat den Vorteil Sie eine einzelne Abfrage ohne Änderungen verwenden in der Kategorie, Unterkategorie oder Organisationsebenen (z geben Sie mir alle Ergebnisse von X Unterkategorie)

suchen

Hope, das hilft.

Adam.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top