Из следующих таблиц я должен получить список пользователей, разрешенных в указанной группе, на основе следующей логики.
MyUser
user_id | user_name
1 | a
2 | b
3 | c
MyGroup
group_id | group_code
1 | G1
2 | G2
3 | G3
user_group
userid | groupid | exclusion
1 | 1 | 0
1 | 2 | 0
2 | 1 | 1
Здесь запрос, который работает для случаев 1 и 3, но не выполняется для случая 2.
SELECT u.id, g.id, g.code, ug.exclusion FROM MyUser u
join MyGroup g
LEFT JOIN user_group ug ON ug.group_id = g.id
AND ug.user_id = 1 -- works for user 2 and 3 but fails for user 1
WHERE (ug.exclusion <> 0 OR ug.exclusion IS NULL)
Итак, в случае записи с исключением = 1, тогда эта запись получает, а другие группы добавляются с нулевым условием. И проблема заключается в том, что нулевые поля также добавляются для исключения = 0, которое не требуется вообще.
Пожалуйста, предложите, можно ли получить список пользователей для данной группы, используя только один запрос
Ожидаемый результат:
g1(a,c), g2(a,b,c), g3(b,c)
Это должно работать или что-то близкое к нему.
select u.user_id, g.group_id, g.code
from MyGroup g
cross join users u
left join user_group allowed ON u.user_id = allowed.user_id AND g.group_id = allowed.group_id AND allowed.exclusion = 0
left join user_group allowbydefault ON u.user_id = allowbydefault.user_id
where (allowed.user_id is not null OR allowbydefault.group_id is null)
-- and g.group_id = 1 -- uncomment to get everyone authorized for group #1
-- and u.user_id = 35 -- uncomment to get every group that user #35 is authorized for
group by u.user_id, g.group_id, g.code
Я использовал SQL Server для проверки этого, но это должно по крайней мере дать вам еще одну точку атаки для MySQL.
left join user_group allowbydefault ON u.user_id = allowbydefault.user_id
вместо: left join user_group allowbydefault ON g.group_id = allowbydefault.group_id
Это даст пользователю все разрешения, если этого пользователя нет в таблице разрешений.