2011-02-02 4 views
1

je les 2 requêtes suivantes qui fonctionnent comme prévu:Combinant deux requêtes

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 

La première requête affiche les enregistrements pour tous les widgets qui @user a accès en fonction du @phrase fourni. La deuxième requête affiche les enregistrements de tous les widgets auxquels @user n'a pas accès en fonction de la @phrase fournie.

Comment puis-je combiner ces 2 requêtes en 1, donc si quelqu'un a un accès basé sur un groupe, mais parce qu'il est dans un autre groupe qui est refusé dans la table de refus, il ne voit pas les résultats?

Je ne sais pas si ma dernière phrase est logique ...

EDIT: Les noms de table Ajouté, des colonnes de table et un peu de données d'échantillon:

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 

Répondre

2

Puisque vous utilisent SQL Server 2005, vous pouvez utiliser 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 prend les résultats de la première requête (allow), et soustrait les résultats de la deuxième requête (deny), vous laissant avec seulement les widgets que l'utilisateur est autorisé et non refusé.

Remarque J'ai modifié vos listes SELECT d'origine, comme EXCEPT exige que les deux requêtes d'avoir (efficacement) la même liste SELECT, et il me semble que ce qui vous intéresse est les widgets.

+0

Votre hypothèse était correcte. – oshirowanen

2

Si je comprends bien, vous voulez à l'union des autorisations (approche la plus restrictive) par laquelle si un utilisateur est autorisé dans un groupe et a nié dans un autre, il doit obtenir ce widget, si tel est le cas, vous pouvez faire cela comme,

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

Il ne devrait pas obtenir le widget s'il est dans un groupe qui est autorisé à accéder et dans un autre groupe auquel l'accès est refusé. Il devrait seulement obtenir le widget s'il est dans un groupe auquel l'accès est autorisé et qui ne fait partie d'aucun groupe auquel l'accès est refusé. – oshirowanen

+0

Cependant, votre script fonctionne, donc vous avez probablement manqué le "non" dans votre phrase ci-dessus qui dit "il devrait obtenir le widget"? – oshirowanen

+0

Vous avez raison, point noté :) @oshirowanen –

3

La façon simple serait d'utiliser une sous requête:

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 
) 

Je ne sais pas comment la performance serait pour ce bien.

EDIT:

Je pense que vous pourriez être en mesure d'éliminer la nécessité d'une sous requête en utilisant les éléments suivants:

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 

Cela dépendra de votre schéma et les données

+0

La première requête fonctionne, mais pas la seconde. On dirait que mon schéma n'est pas compatible. – oshirowanen

+0

@oshirowanen - Si vous souhaitez utiliser la 2ème requête, ajoutez un exemple de votre schéma et de vos données (si vous le pouvez) à votre question et je vais essayer de la modifier pour qu'elle fonctionne correctement. – codingbadger

+0

J'ai ajouté tout ce que vous vouliez. Je pense. – oshirowanen