2017-11-13 1 views
2

Ich frage mich, wie kann ich eine erfolgreiche Abfrage für eine Hierarchie Struktur, die ich mit meinen Benutzern habe. Ich hatte eine ähnliche Frage gestellt, aber die Struktur änderte sich, wo jetzt nur Executives Kunden zugewiesen bekommen können.Hierarchy Query

Es gibt dieses Maß an Benutzer:

  1. Direktor
  2. -Manager
  3. Vorstand

Beispieltabelle NUTZER:

ID username privilege parent_ID 
1  Director1 1   null 
2  Director2 1   null 
3  Manager1 2   1 
4  Manager2 2   1 
5  Manager3 2   2 
6  Executive1 3   3 
7  Executive2 3   3 
8  Executive3 3   4 
9  Executive4 3   4 
10 Executive5 3   5 
11 Executive6 3   5 

Und sie ihre „Kunden haben ".

Beispieltabelle KUNDEN

ID name User_ID 
1 c1 11 
2 c2 10 
3 c3 10 
4 c4 9 
5 c5 8 
6 c6 7 
7 c7 6 

Mein Problem in ist, welche Art von beitreten soll ich so machen, dass jeder Benutzer in der Lage sein wird, nur die Kunden zu sehen, dass sie erlaubt sind, die die Regel wäre, dass sie kann nur Kunden von den Führungskräften unter ihnen sehen, und Führungskräfte können nur ihre eigenen Kunden sehen.

Diagram

Zum Beispiel in der Abbildung oben, wenn die Nutzer waren seine Kunden zu überprüfen, sollte er sehen:

Director1: C7, C6, C5, C4

Director2: C3, C2, C1

Manager1: C7, C6

Manager2: C5, C4

Manager3: C3, C2, C1

und die Führungskräfte würden nur ihre eigenen Kunden sehen.

Antwort

2

Der richtige Weg, dies zu lösen, ist mit einer rekursiven CTE-Abfrage, die in MySQL 8.0 kommen werden:

WITH RECURSIVE h AS (
    SELECT ID FROM USERS WHERE ID = ? 
    UNION 
    SELECT ID FROM USERS AS u JOIN h ON u.parent_ID = h.ID 
) 
SELECT c.* 
FROM h 
JOIN COSTUMERS AS c ON c.User_ID = h.ID; 

Wenn Sie noch MySQL 5.7 oder älter verwenden, müssen Sie es tun mehr ungeschickt https://dev.mysql.com/doc/refman/8.0/en/with.html . Sie haben einen Vorteil, dass Ihre Hierarchie eine feste maximale Tiefe hat.

SELECT c.* 
FROM (
    SELECT e.ID FROM USERS AS e 
    WHERE e.ID = ? 
    UNION ALL 
    SELECT e.ID FROM USERS AS e 
    JOIN USERS AS m ON e.parent_ID = m.ID 
    WHERE m.ID = ? 
    UNION ALL 
    SELECT e.ID FROM USERS AS e 
    JOIN USERS AS m ON e.parent_ID = m.ID 
    JOIN USERS AS d ON m.parent_ID = d.ID 
    WHERE d.ID = ? 
) AS h 
JOIN COSTUMERS AS c ON c.User_ID = h.ID; 

Ich gehe davon aus, dass wie Closure Tabelle der Hierarchie in einer anderen Gestaltung der Umstrukturierung ist nicht eine Möglichkeit. Aber wenn Sie in anderen Designs interessiert sind, sehen meine Antwort auf What is the most efficient/elegant way to parse a flat table into a tree?

Oder meine Präsentation https://www.slideshare.net/billkarwin/models-for-hierarchical-data

Oder mein Buch SQL Antipatterns: Avoiding the Pitfalls of Database Programming.

+0

Vielen Dank, kennen Sie die Vorteile von MYSQL 8? Soll ich die dev-Version dafür verwenden? ist die Version 5.7 zu ressourcenintensiv, dass es eine gute Idee ist, sie zu benutzen oder gar auf 8.0 zu warten? –

+0

auch, im Lesen Ihrer Präsentation, es ist nicht außerhalb des Umfangs, alles neu zu strukturieren, da ich in einer Phase bin, wo ich meine gesamte Datenbank strukturiere, damit ich noch Änderungen vornehmen kann. wäre Schließtisch besser? –

+0

MySQL 8.0 befindet sich derzeit noch im Status "Release Candidate". Es ist noch zu früh, um zu sagen, wann es für den Produktionseinsatz bereit sein wird, also sollten Sie sorgfältig testen. In der MySQL-Community gibt es einen running witz, um zu verhindern, dass eine neue Hauptversion übernommen wird, bis sie ihre ".20" - Version, d. H. MySQL 8.0.20, erreicht. Dann sollten größere Fehler und grobe Fehler behoben sein. Diese Regel kommt vom ehemaligen Direktor der Entwicklung für MySQL: https://www.flamingspork.com/blog/2013/08/01/stewarts-dot-twenty-rule/ –