Объединение двух запросов - PullRequest
1 голос
/ 02 февраля 2011

У меня есть следующие 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.

Как я могу объединить эти 2 запроса в 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

Ответы [ 3 ]

3 голосов
/ 02 февраля 2011

Простой способ будет использовать подзапрос:

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

Это будет зависеть от вашей схемы и данных

2 голосов
/ 02 февраля 2011

Поскольку вы используете 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, и мне кажется, что вас интересуют виджеты.

2 голосов
/ 02 февраля 2011

Если я правильно понимаю, вы хотите объединить разрешения (наиболее ограниченный подход), в соответствии с которым, если пользователь разрешен в одной группе и запрещен в другой, он должен получить этот виджет, в этом случае вы можете сделать это ,

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
        )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...