我想知道如何成功查询我与用户的层次结构。我曾发布过类似的问题,但结构发生了变化,现在只有高管才能将客户分配给他们。
用户有以下级别:
- 董事
- 经理
- 执行官
示例表用户:
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
经理3:C3,C2,C1
高管们只能看到自己的客户。
最佳答案
解决这个问题的正确方法是使用递归 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;
我假设将您的层次结构重组为另一种设计(例如闭包表)是不可能的。但如果您对其他设计感兴趣,请参阅我对 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 Volume 1: Avoiding the Pitfalls of Database Programming .
关于mysql - 层次查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47271194/