我想知道如何成功查询我与用户的层次结构。我发布了一个类似的问题,但结构发生了变化,现在只有高管可以为他们分配客户。
有这样级别的用户:
示例表USERS:
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
他们会有他们的“顾客”。
示例表COSTUMERS
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
我的问题在于我应该建立什么样的联接,以便每个用户只能看到他们被允许的客户,规则是他们只能看到他们下面的高管的客户,以及高管们只能看到他们自己的客户。
例如,在上图中,如果用户要检查他的客户,他应该看到:
导演1:C7,C6,C5,C4
导演2:C3,C2,C1
经理1:C7,C6
经理2:C5,C4
Manager3:C3,C2,C1
高管只会看到自己的客户。答案 0 :(得分:2)
解决这个问题的正确方法是使用递归CTE查询,它将在MySQL 8.0中出现:https://dev.mysql.com/doc/refman/8.0/en/with.html
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;
如果您仍在使用MySQL 5.7或更早版本,则需要更加笨拙地进行操作。您有一个优点,即您的层次结构具有固定的最大深度。
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;
我假设将您的层次结构重组为像Closure Table这样的另一种设计是不可能的。但如果您对其他设计感兴趣,请参阅我对What is the most efficient/elegant way to parse a flat table into a tree?
的回答或我的演讲https://www.slideshare.net/billkarwin/models-for-hierarchical-data
或我的书SQL Antipatterns: Avoiding the Pitfalls of Database Programming。