Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server CTE层次结构问题_Sql Server_Common Table Expression_Hierarchical Data_Recursive Query - Fatal编程技术网

Sql server SQL Server CTE层次结构问题

Sql 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

我有一个权限和角色的应用程序

我有这样的层次结构:

国家

……地区

……城市

……协会

……中心

学校

等级

我将其命名为EntityLevel

| 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