2011-02-02 148 views
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 

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 

回答

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 

Thi S可在​​第一(允許)查詢的結果,並減去的第二(拒絕)查詢的結果,讓你只用那些在允許用戶和沒有否認小部件。

注意我已經改變了原來的SELECT清單,EXCEPT需要兩個查詢有(有效)相同SELECT名單,並在我看來,你有興趣在什麼是小部件。

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 
     ) 
+0

,如果他是在被允許接入1組,在被拒絕訪問另一組他應該沒有獲得小部件。如果他在一個允許訪問的組中,並且不屬於被拒絕訪問的任何組,則他只應該獲取該組件。 – oshirowanen 2011-02-02 11:47:01

+0

但是,你的腳本是可以工作的,所以你可能錯過了上面的那個「他應該得到小部件」的句子中的「不」。 – oshirowanen 2011-02-02 11:51:38

+0

你R右,點指出:) @oshirowanen – 2011-02-03 05:08:48

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 

這將取決於你的架構和數據