为简单起见,假设我有以下表格:
role
id name inherits
----------------------------------
1 Base null
2 Role2 1
3 Role3 1
4 Role3Child 3
item
id name org_id
----------------------------------
1 item1 4210
2 item2 4210
3 item3 4210
4 item4 4210
5 item5 4210
6 item6 4210
role_item_junction
id role_id item_id item_value
----------------------------------
1 1 1 true
2 1 2 false
3 2 3 D
4 3 3 F
5 4 4 12
role_id 4这里通过继承自role_id 1继承的role_id 3继承了所有项目。
当我查询与role_id 4有关的所有项目时,我想返回:
如何编写一个返回role_id 4应该有权访问的所有项的查询?当我查询role_id 4时,我希望输出看起来类似于以下内容:
id(item.id) org_id name(item.name) item_value
------------------------------------------------------------------
1 4210 item1 true
2 4210 item2 false
3 4210 item3 F
4 4210 item4 12
5 4210 item5 NULL <--not in the junction table
6 4210 item6 NULL <--not in the junction table
不知道如何从左连接返回联结表中的继承项值:
@orgid varchar(5) = '4210',
@roleid int = 4
SELECT item.*, ri.item_value AS selected_item_value
--SNIP LOTS OF OTHER COLUMNS RETURNED
FROM item
LEFT JOIN role_item AS ri ON item.id = ri.item_id
AND ri.role_id = @roleid
???? how do I return the ri.item_value of items that roleid 4 inherits from?
--SNIP LOTS OF OTHER IRRELEVANT JOINS
WHERE
((@orgid IS NULL or @orgid = '') or item.org_id = @orgid) AND
item.date_archived IS NULL
AND ri.date_archived IS NULL
答案 0 :(得分:1)
在没有递归CTE的情况下,我想不出一个简单的方法来解决它,但这应该有效:
;WITH roleCascaded AS
(SELECT id, id as inherits
FROM role
UNION ALL
SELECT r2.id, r1.inherits
FROM role r1
INNER JOIN roleCascaded r2 on r1.id = r2.inherits AND r1.inherits IS NOT NULL
)
SELECT item.*, ri.item_value AS selected_item_value
FROM item
LEFT OUTER JOIN role_item AS ri ON item.id = ri.item_id
LEFT OUTER JOIN roleCascaded AS rc ON rc.inherits = ri.role_id AND rc.id = @roleid
WHERE
((@orgid IS NULL or @orgid = '') or item.org_id = @orgid) AND
item.date_archived IS NULL
AND ri.date_archived IS NULL