我有以下2个查询按预期工作:
declare @user varchar(3)
declare @phrase varchar(255)
set @user = 'xyz'
set @phrase = '%nav%'
select ug.*, wap.*, w.*
from user_groups ug
inner join widget_access_permissions wap on ug.id = wap.allowed
inner join widgets w on wap.widget_id = w.widget_id
where ug.employee_code = @user
and w.widget_name like @phrase
select w.widget_id, ug.*, wdp.*, w.*
from user_groups ug
inner join widget_deny_permissions wdp on ug.id = wdp.denied
inner join widgets w on wdp.widget_id = w.widget_id
where ug.employee_code = @user
and w.widget_name like @phrase
第一个查询显示@user根据提供的@phrase访问的任何小部件的记录。第二个查询显示@user根据提供的@phrase无权访问的任何小部件的记录。
如何将这两个查询合并为1,如果某人有基于某个组的访问权限,但因为他在另一个拒绝表中拒绝的组中,他就看不到结果?
我不知道我的最后一句话是否有意义......
编辑:添加了表名,表列和一些示例数据:
user_groups
table
id
display_value
employee_code
dept
persnl_typ_code
sample row 1
1000
group 1
xyz
i.t.
gen
sample row 2
1008
group 2
xyz
i.t.
gen
==========
widget_access_permissions
table
id
widget_id
allowed
sample row
0
0
1000
==========
widget_deny_permissons
table
id
widget_id
denied
sample row
0
0
1008
==========
widgets
table
widget_id
widget_name
widget_description
widget_header
widget_sub_header
widget_content
sample row
0
widget name goes here
widget description goes here
widget header goes here
widget sub header goes here
widget content goes here
答案 0 :(得分:3)
简单的方法是使用子查询:
declare @user varchar(3)
declare @phrase varchar(255)
set @user = 'xyz'
set @phrase = '%nav%'
select ug.*, wap.*, w.*
from user_groups ug
inner join widget_access_permissions wap on ug.id = wap.allowed
inner join widgets w on wap.widget_id = w.widget_id
where ug.employee_code = @user
and w.widget_name like @phrase
and w.WidgetId not in (
select w.widget_id
from user_groups ug
inner join widget_deny_permissions wdp on ug.id = wdp.denied
inner join widgets w on wdp.widget_id = w.widget_id
where ug.employee_code = @user
and w.widget_name like @phrase
)
不确定性能如何。
编辑:
我认为您可以通过使用以下内容来删除子查询的需要:
declare @user varchar(3)
declare @phrase varchar(255)
set @user = 'xyz'
set @phrase = '%nav%'
select ug.*, wap.*, w.*
from user_groups ug
inner join widget_access_permissions wap on ug.id = wap.allowed
inner join widgets w on wap.widget_id = w.widget_id
Left Join widget_deny_permissions wdp on ug.id = wdp.denied
and w.widget_id = wdp.widget_id
where ug.employee_code = @user
and w.widget_name like @phrase
and wdp.Id Is Null
这取决于您的架构和数据
答案 1 :(得分:2)
如果我理解正确,你想要联合权限(最严格的方法),如果一个组允许用户而另一个组被拒绝,他应该得到那个小部件,如果是这种情况,你可以这样做,
declare @user varchar(3)
declare @phrase varchar(255)
set @user = 'xyz'
set @phrase = '%nav%'
select ug.*, wap.*, w.*
from user_groups ug
inner join widget_access_permissions wap on ug.id = wap.allowed
inner join widgets w on wap.widget_id = w.widget_id
where ug.employee_code = @user
and w.widget_name like @phrase
and w.widget_id NOT IN (
select w.widget_id
from user_groups ug
inner join widget_deny_permissions wdp on ug.id = wdp.denied
inner join widgets w on wdp.widget_id = w.widget_id
where ug.employee_code = @user
and w.widget_name like @phrase
)
答案 2 :(得分:2)
由于您使用的是SQL Server 2005,因此可以使用EXCEPT
:
select w.*
from user_groups ug
inner join widget_access_permissions wap on ug.id = wap.allowed
inner join widgets w on wap.widget_id = w.widget_id
where ug.employee_code = @user
and w.widget_name like @phrase
EXCEPT
select w.*
from user_groups ug
inner join widget_deny_permissions wdp on ug.id = wdp.denied
inner join widgets w on wdp.widget_id = w.widget_id
where ug.employee_code = @user
and w.widget_name like @phrase
这会获取第一个(允许)查询的结果,减去第二个(拒绝)查询的结果,只留下那些允许用户被拒绝的小部件。
注意我已更改了原始SELECT
列表,因为EXCEPT
要求两个查询(有效)具有相同的SELECT
列表,在我看来,您感兴趣的是什么in是小部件。