从具有父子关系的表中获取访问权限
Get access from tables with parent child relationship
我有以下架构来存储节点层次结构和角色对节点的访问。
角色从父节点的访问权限集中继承对子节点的访问权限,除非它在 accessdetails table.
中有条目
我想获取给定角色的特定节点的后代、级别和访问权限。在这种情况下,角色为 1,父级为 'b'.
SQLfiddle link
CREATE TABLE hierarchy
(parent varchar(1), node varchar(1))
;
CREATE TABLE accessdetails
(role integer, node varchar(1), access integer)
;
INSERT INTO hierarchy
(parent, node)
VALUES
(NULL, 'a'),
('a', 'b'),
('b', 'c'),
('c', 'p'),
('p', 'q'),
('q', 'r'),
('b', 'd'),
('d', 'j'),
('a', 'e'),
('e', 'f'),
('f', 'x')
;
/*
0-no,1-r,2-w,3-full
*/
insert into accessdetails
(role, node, access)
values
(1, 'b', 3),
(1, 'c', 2),
(1, 'p', 0)
;
以下查询 returns 级别和后代正确但无法获得正确的访问权限。
with recursive
descendants as
( select parent, node as descendant, 1 as level,
(select access from accessdetails where node=hierarchy.node and role=1) as access
from hierarchy where parent = 'b'
union all
select d.parent, s.node, d.level + 1,
(select access from accessdetails where node=s.node and role=1) as access
from descendants as d
join hierarchy s
on d.descendant = s.parent
)
select descendant, level, access
from descendants
order by parent, level, descendant ;
Current output:
descendant level access
c 1 2
d 1 (null)
j 2 (null)
p 2 0
q 3 (null)
r 4 (null)
Expected output:
descendant level access
c 1 2
d 1 3
j 2 3
p 2 0
q 3 0
r 4 0
我该如何实现?
最终 solution 对架构稍作修改:
这里的问题是您以 b
作为父节点的节点开始层次结构。这些是节点 c
和 d
。节点 c
具有显式分配的访问权限 2
,但节点 d
没有。查询没有“看到”分配给节点 b
的 3
的访问,因为该行不包含在查询中。
这个查询是我解决问题的方式。它生成整个层次结构,然后将其限制为具有 b
作为其路径中第一个节点的行。
with recursive descendants as (
select h.parent, h.node as descendant, 1 as level, ad.access,
array[h.node]::text[] as path
from hierarchy h
left join accessdetails ad on ad.node = h.node
union all
select d.parent, s.node, d.level + 1,
coalesce(ad.access, d.access), d.path||s.node::text
from descendants as d
join hierarchy s
on d.descendant = s.parent
left join accessdetails ad on ad.node = s.node
)
select descendant, level, access, path
from descendants
where path[1] = 'b'
order by parent, level, descendant ;
我有以下架构来存储节点层次结构和角色对节点的访问。 角色从父节点的访问权限集中继承对子节点的访问权限,除非它在 accessdetails table.
中有条目我想获取给定角色的特定节点的后代、级别和访问权限。在这种情况下,角色为 1,父级为 'b'.
SQLfiddle link
CREATE TABLE hierarchy
(parent varchar(1), node varchar(1))
;
CREATE TABLE accessdetails
(role integer, node varchar(1), access integer)
;
INSERT INTO hierarchy
(parent, node)
VALUES
(NULL, 'a'),
('a', 'b'),
('b', 'c'),
('c', 'p'),
('p', 'q'),
('q', 'r'),
('b', 'd'),
('d', 'j'),
('a', 'e'),
('e', 'f'),
('f', 'x')
;
/*
0-no,1-r,2-w,3-full
*/
insert into accessdetails
(role, node, access)
values
(1, 'b', 3),
(1, 'c', 2),
(1, 'p', 0)
;
以下查询 returns 级别和后代正确但无法获得正确的访问权限。
with recursive
descendants as
( select parent, node as descendant, 1 as level,
(select access from accessdetails where node=hierarchy.node and role=1) as access
from hierarchy where parent = 'b'
union all
select d.parent, s.node, d.level + 1,
(select access from accessdetails where node=s.node and role=1) as access
from descendants as d
join hierarchy s
on d.descendant = s.parent
)
select descendant, level, access
from descendants
order by parent, level, descendant ;
Current output:
descendant level access
c 1 2
d 1 (null)
j 2 (null)
p 2 0
q 3 (null)
r 4 (null)
Expected output:
descendant level access
c 1 2
d 1 3
j 2 3
p 2 0
q 3 0
r 4 0
我该如何实现?
最终 solution 对架构稍作修改:
这里的问题是您以 b
作为父节点的节点开始层次结构。这些是节点 c
和 d
。节点 c
具有显式分配的访问权限 2
,但节点 d
没有。查询没有“看到”分配给节点 b
的 3
的访问,因为该行不包含在查询中。
这个查询是我解决问题的方式。它生成整个层次结构,然后将其限制为具有 b
作为其路径中第一个节点的行。
with recursive descendants as (
select h.parent, h.node as descendant, 1 as level, ad.access,
array[h.node]::text[] as path
from hierarchy h
left join accessdetails ad on ad.node = h.node
union all
select d.parent, s.node, d.level + 1,
coalesce(ad.access, d.access), d.path||s.node::text
from descendants as d
join hierarchy s
on d.descendant = s.parent
left join accessdetails ad on ad.node = s.node
)
select descendant, level, access, path
from descendants
where path[1] = 'b'
order by parent, level, descendant ;