Есть 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)
Мне это не очень нравится, особенно подзапрос в фильтре.
Может присоветуете что получше?
А>Мне это не очень нравится, особенно подзапрос в фильтре.
А>Может присоветуете что получше?
Ну попробуй 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 = '...'
Здравствуйте, Аноним, Вы писали:
А>Есть 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 в своем запросе, у одной роли могут быть отчеты дубликаты?
O>А зачем вы используете distinct в своем запросе, у одной роли могут быть отчеты дубликаты?
Он вот с этим борется
FROM Report r
LEFT JOIN Report_Role rr ON rr.ID_Report = r.ID
т.е. отчет может быть разрешён нескольким ролям
Здравствуйте, 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)