2011-02-02 10 views
1

I가 예상대로 작동은 다음 두 쿼리 :결합하여 두 개의 쿼리

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에 따라 데이터에 액세스 할 수있는 임의의 위젯에 대한 기록을 보여줍니다. 두 번째 쿼리는 제공된 @phrase를 기반으로 @user가 액세스 할 수없는 위젯에 대한 레코드를 보여줍니다.

누군가이 그룹을 기반으로 액세스 권한을 가지고 있지만 거부 테이블에 거부 된 다른 그룹에 있기 때문에 결과를 볼 수 없으므로이 두 쿼리를 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는 첫 번째 (허용) 쿼리의 결과를 가져오고 은 두 번째 (거부) 쿼리의 결과를에서 뺍니다. 사용자가 허용되거나 거부되지 않는 위젯 만 남겨 둡니다.

주 나는 EXCEPT이 (효과적으로) 같은 SELECT 목록을 가지고 두 개의 쿼리를 필요로, 원래 SELECT 목록을 변경했으며, 당신이 관심있는 것은 위젯입니다 날 것으로 보인다.

+0

귀하의 가정은 정확합니다. – oshirowanen

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

+0

그러나 스크립트가 작동하므로 위의 문장에서 "위젯을 가져와야합니다"라는 "not"가 누락 된 것일 수 있습니다. – oshirowanen

+0

당신이 맞아요, 지적했다 :) @oshirowanen –

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 

이 당신 때문에

+0

첫 번째 쿼리는 작동하지만 두 번째 쿼리는 작동하지 않습니다. 내 스키마가 호환되지 않는 것 같습니다. – oshirowanen

+0

@oshirowanen - 두 번째 쿼리를 사용하려면 질문에 대한 스키마 및 데이터 예제를 추가하십시오. 올바르게 작동하도록 수정하려고합니다. – codingbadger

+0

내가 원하는 것을 모두 추가했습니다. 나는 생각한다. – oshirowanen

관련 문제