Помогите с запросом для MS SQL
От: Аноним  
Дата: 25.11.13 11:41
Оценка:
Есть 4 таблицы:
Report (ID, Name,...) — таблица описания отчетов
Role (ID, Name) — классическая таблица ролей
User_Role (Login, ID_Role) — классическая таблица ролей пользователя

Report_Role (ID_Report, ID_Role) — пользователям каких ролей доступен отчет,
если для отчета нет роли, то можно всем

Нужно проверить доступность отчетов текущему пользователю. Сделал так:
SELECT DISTINCT  r.* FROM Report r
    LEFT JOIN Report_Role rr ON rr.ID_Report = r.ID 
WHERE rr.ID_Role IS NULL  OR
    EXISTS (select 1 from User_Role ur where ur.Login = 'admin' AND rr.ID_Role=ur.ID_Role)

Мне это не очень нравится, особенно подзапрос в фильтре.
Может присоветуете что получше?
Re: Помогите с запросом для MS SQL
От: avpavlov  
Дата: 25.11.13 13:38
Оценка:
А>Мне это не очень нравится, особенно подзапрос в фильтре.
А>Может присоветуете что получше?

Ну попробуй 2 запроса через union, облегчишь оптимизатору жизнь

SELECT 
  r.* 
FROM 
  Report r 
  LEFT JOIN Report_Role rr ON rr.ID_Report = r.ID 
WHERE 
  rr.ID_Role IS NULL
UNION SELECT 
    r.* 
FROM 
  Report r 
  INNER JOIN Report_Role rr ON rr.ID_Report = r.ID 
  INNER JOIN User_Role ur ON rr.ID_Role=ur.ID_Role
WHERE 
  ur.Login = '...'
Re: Помогите с запросом для MS SQL
От: Olaf Россия  
Дата: 25.11.13 15:38
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть 4 таблицы:


А>Нужно проверить доступность отчетов текущему пользователю. Сделал так:


А>Мне это не очень нравится, особенно подзапрос в фильтре.

А>Может присоветуете что получше?

Можно конечно и так, но вот будет ли заметный прирост производительности..
select r.*
from report r
where r.id in 
(
    select rr.id_report
    from Report_Role rr
    where rr.id_role = (select ur.id_role from User_Role ur where ur.Login = 'admin') 
          or rr.id_role is null
)

А зачем вы используете distinct в своем запросе, у одной роли могут быть отчеты дубликаты?
Re[2]: Помогите с запросом для MS SQL
От: avpavlov  
Дата: 25.11.13 15:57
Оценка:
O>А зачем вы используете distinct в своем запросе, у одной роли могут быть отчеты дубликаты?

Он вот с этим борется

FROM Report r
    LEFT JOIN Report_Role rr ON rr.ID_Report = r.ID


т.е. отчет может быть разрешён нескольким ролям
Re[3]: Помогите с запросом для MS SQL
От: Olaf Россия  
Дата: 25.11.13 16:29
Оценка:
Здравствуйте, avpavlov, Вы писали:
O>>А зачем вы используете distinct в своем запросе, у одной роли могут быть отчеты дубликаты?

A>Он вот с этим борется


A>
A>FROM Report r
A>    LEFT JOIN Report_Role rr ON rr.ID_Report = r.ID 
A>

A>т.е. отчет может быть разрешён нескольким ролям

Такое может быть, но автор в своем запросе исключает эту ситуацию использованием коррелированного подзапроса для конкретного пользователя через EXISTS
WHERE ... OR
    EXISTS (select 1 from User_Role ur where ur.Login = 'admin' AND rr.ID_Role=ur.ID_Role)
Re[4]: Помогите с запросом для MS SQL
От: avpavlov  
Дата: 25.11.13 16:51
Оценка: +1
А если юзер имеет 2 роли и обеим отчет разрешен?
Re[5]: Помогите с запросом для MS SQL
От: Аноним  
Дата: 26.11.13 05:24
Оценка:
Здравствуйте, avpavlov, Вы писали:

A>А если юзер имеет 2 роли и обеим отчет разрешен?


именно так, юзер может иметь сколько угодно ролей и доступ к отчету могут иметь много ролей, отсюда и DISTINCT
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.