Sql server SQL Server CTE层次结构问题
我有一个权限和角色的应用程序 我有这样的层次结构: 国家 ……地区 ……城市 ……协会 ……中心 学校 等级 我将其命名为EntityLevelSql server SQL Server CTE层次结构问题,sql-server,common-table-expression,hierarchical-data,recursive-query,Sql Server,Common Table Expression,Hierarchical Data,Recursive Query,我有一个权限和角色的应用程序 我有这样的层次结构: 国家 ……地区 ……城市 ……协会 ……中心 学校 等级 我将其命名为EntityLevel | ID | Name | ParentID | |----|-------------|----------| | 1 | Country | Null | | 2 | Region | 1 | | 3 | City | 2 | | 4 | Associatio
| ID | Name | ParentID |
|----|-------------|----------|
| 1 | Country | Null |
| 2 | Region | 1 |
| 3 | City | 2 |
| 4 | Association | 3 |
| 5 | Center | 4 |
| 6 | School | 5 |
| 7 | Class | 6 |
我也有一个组表,这意味着工作
| ID | Name | EntityLevels |
|----|--------------------|--------------|
| 1 | CountryAdmins | 1 |
| 2 | Region Supervisors | 2 |
用户表如下所示
| ID | Name |
|----|-------|
| 1 | User1 |
| 2 | User2 |
现在我有了一个UserJobs表或UserGroups
| ID | UserID | GroupdID | EntityID |
|----|--------|----------|----------|
| 1 | User1 | 1 | 1 |
| 2 | User2 | 2 | 2 |
| 3 | User3 | 4 | 38 |
现在的问题是,我如何根据每个用户的级别来确定他们的职责
对于EAX示例:
user1必须具有查看其级别下所有用户的所有角色和权限,因为他在组1中,而组1位于国家/地区级别的EntityLevel 1中
我试着做一些类似的事情,但它没有像预期的那样工作,它只给我根,而没有任何其他子根
;WITH MyCTE AS (
SELECT T1.ID, UserId, 0 AS TreeLevel, CAST(T1.ID AS VARCHAR(255)) AS TreePath FROM UserJobs T1
inner join EntityLevel el on t1.GroupId = el.Id WHERE EL.ParentID IS NULL
UNION ALL
SELECT T2.ID, T2.UserId, TreeLevel + 1, CAST(TreePath + '.' + CAST(T2.ID AS VARCHAR(255)) AS VARCHAR(255)) AS TreePath
FROM UserJobs T2
inner join EntityLevel el on T2.GroupId = el.Id
INNER JOIN
MyCTE itms ON itms.ID = EL.ParentID
)
SELECT ID, TreeLevel, TreePath
FROM MyCTE
ORDER BY TreePath;
架构和数据的脚本
小提琴
编辑:预期结果将是:
脚本和数据版本2
有什么解决办法吗?你能试试这个吗?评论后编辑
;WITH MyCTE AS (
SELECT T1.ID, UserId, NULL AS PARENT_ID, T1.GroupID, G.EntityLevelID
FROM UserJobs T1
INNER JOIN [GROUP] G ON T1.GROUPID = G.ID
inner join EntityLevel el on G.EntityLevelID = el.Id
WHERE T1.UserID = 1 /* Write here the user id you want */
UNION ALL
SELECT T2.ID, T2.UserId, EL.ParentID, T2.GroupID, G.EntityLevelID
FROM UserJobs T2
INNER JOIN [GROUP] G ON T2.GROUPID = G.ID
inner join EntityLevel el on G.EntityLevelID = el.Id
INNER JOIN MyCTE itms ON EL.ParentID >= itms.ID
)
SELECT B.*, C.*, A.*
FROM (SELECT DISTINCT * FROM MyCTE) A
INNER JOIN [USER] B ON A.UserID = B.ID
INNER JOIN [Group] C ON A.GroupID = C.ID
;
输出:
ID Name Mobile ID Name EntityLevelID ID UserId PARENT_ID GroupID EntityLevelID
1 1 Loai 000000 1 SA 1 1 1 NULL 1 1
2 3 User2 2222 3 region admin 2 3 3 1 3 2
3 4 User3 3333 4 region Supervisor 2 4 4 1 4 2
4 5 User4 4444 5 manager 4 5 5 3 5 4
5 6 user5 5555 6 supervisor 5 6 6 4 6 5
6 7 user6 6548 7 teacher 7 7 7 6 7 7
IMHO您必须构建整个实体树,然后使用它与其他表连接 看看你想要的结果,我不清楚实体和城市、地区、阶级等之间的关系 显然,根据实体的名称,我知道1=国家,2=地区等等,但我在表架构中找不到任何允许获取此信息的字段,除了:
CASE WHEN Entity.ID = 1 (SELECT Name FROM Country WHERE ID = Entity.ID) END
WHEN Entity.ID = 2 (SELECT Name FROM Region WHERE ID = Entity.ID) END
WHEN Entity.ID = 3 (SELECT Name FROM City WHERE ID = Entity.ID) END
...
END as EntityName
我建议您构建一个UDF或SP来获取实体的名称,并在下一个脚本中使用它
DBFIDLE对作为示例数据发布的所有脚本投一票。。。帮助你更容易。好done@etsa谢谢,如果有什么不清楚的地方,我可以向您澄清。您是否在您的SELECT中错贴了任何表名和myCTE。。。?你能检查一下吗?@etsa试试看now@etsa该查询应该获取一个用户id参数,并将树中提供的用户下的所有用户删除,我从用户角度需要它,因为我需要提供一个用户id,然后该查询应该为我提供该用户id下的所有用户。在示例的树上,如果我提供一个userID=4,并且该用户位于中心级别,那么所需的查询应该返回该中心下的所有用户。您能看到我编辑的查询吗?我不太清楚您表中的某些字段,例如UserJobs中的EntityID UserJobs中的EntityID包含国家、地区、城市等的实体ID。。。等,用户拥有该组。e、 g.如果UserJobs表中的用户的GroupID=3,则表示该用户具有region admin角色,您将看到EntityLevel为2,表示=region。现在在UserJobs中,用户最多分配给特定区域,即EntityID=2=riyadh。实际上,我认为您可以使用更合适的名称EntityID->RegionID?:-谢谢,但是这个查询提供了EntityLevel表透视图中的数据,而我需要的是用户透视图中的树结构。e、 g.我需要知道功率对每个用户的影响。如果USER1是一个id EntityID=1的国家级别,即KSA,我需要查询以提供该国家id下的所有内容。让我们。嗨,我们可以再次打开讨论吗?因为结果我不清楚,并且与我期望的不一样。
ID Name Mobile ID Name EntityLevelID ID UserId PARENT_ID GroupID EntityLevelID
1 1 Loai 000000 1 SA 1 1 1 NULL 1 1
2 3 User2 2222 3 region admin 2 3 3 1 3 2
3 4 User3 3333 4 region Supervisor 2 4 4 1 4 2
4 5 User4 4444 5 manager 4 5 5 3 5 4
5 6 user5 5555 6 supervisor 5 6 6 4 6 5
6 7 user6 6548 7 teacher 7 7 7 6 7 7
CASE WHEN Entity.ID = 1 (SELECT Name FROM Country WHERE ID = Entity.ID) END
WHEN Entity.ID = 2 (SELECT Name FROM Region WHERE ID = Entity.ID) END
WHEN Entity.ID = 3 (SELECT Name FROM City WHERE ID = Entity.ID) END
...
END as EntityName
;WITH tree AS
(
SELECT e1.ID, e1.Name, e1.ParentID, [level] = 1
FROM EntityLevel e1
WHERE e1.ParentID = (SELECT EntityID FROM UserJobs WHERE UserID = 1)
UNION ALL
SELECT e2.ID, e2.Name, e2.ParentID, [level] = tree.[level] + 1
FROM EntityLevel e2
INNER JOIN tree
ON e2.ParentID = tree.ID
)
SELECT EntityLevelID, UserName, GroupID, GroupName, EntityID, EntityName
FROM tree t
INNER JOIN (SELECT gr.entitylevelid,
us.Name UserName,
gr.Name GroupName,
el.Name as EntityName,
gr.ID as GroupID,
el.ID as EntityID
FROM userjobs uj
INNER JOIN [group] gr
ON gr.id = uj.groupid
INNER JOIN entitylevel el
ON el.id = gr.entitylevelid
INNER JOIN [user] us
ON us.id = uj.userid) t1
ON t.ID = t1.EntityLevelID
OPTION (MAXRECURSION 0)
;
GO
EntityLevelID | UserName | GroupID | GroupName | EntityID | EntityName
------------: | :------- | ------: | :---------------- | -------: | :----------
2 | User2 | 3 | region admin | 2 | Region
2 | User3 | 4 | region Supervisor | 2 | Region
4 | User4 | 5 | manager | 4 | Association
5 | user5 | 6 | supervisor | 5 | Center
7 | user6 | 7 | teacher | 7 | Class