1) список А (например пользователей)
2) список Б (например ролей)
3) список В (отношение пользователь-роль)
Задача: Выбрать уникальные роли из колонки Б, которые есть у всех пользователей из колонки А. При этом, если роль не встречается хотя бы у одного пользователя, то её отбрасываем.
в итоге родилось вот такое вот решение на @-формулах (переменные list, roles и users как бы результат выборки из представления):
list := "User1~role1":"User2~role3":"User2~role1":"User3~role1":"User3~role3":"User4~role1":"User4~role2";
roles:="role1":"role2":"role3";
users := "User1":"User2":"User3":"User4";
t0:=users*+"~"*+roles;
t1:=@Replace(t0; list; "");
t2:=@Explode(t1; "~");
t3:=@Replace(t2; roles; "");
t4:=@Unique(@Replace(t2; t3; ""));
result := @Unique(@Replace(roles; t4; ""));
result
Результат вычисления: role1
А теперь по порядку распишу каждую строчку:
создаём все возможные пересечения пользователь~роль
t0:=users*+"~"*+roles; | User1~role1 User1~role2 User1~role3 User2~role1 User2~role2 User2~role3 User3~role1 User3~role2 User3~role3 User4~role1 User4~role2 User4~role3 |
---|
удаляем все пересечения, которые уже есть в list:
t1:=@Replace(t0; list; ""); | User1~role2 User1~role3 User2~role2 User3~role2 User4~role3 |
---|
Преобразуем список t1 в список с пользователями и ролями отдельно в каждой "строке"
t2:=@Explode(t1; "~"); | User1 role2 User1 role3 User2 role2 User3 role2 User4 role3 |
---|
удаляем из списка t2 все роли, оставляя только пользователей
t3:=@Replace(t2; roles; ""); | User1 User1 User2 User3 User4 |
---|
А теперь из списка t2 удаляем всех пользователей, полученных в списке t3. Тем самым мы получаем роли, которые не упоминались у каждого из пользователя в списке users
t4:=@Unique(@Replace(t2; t3; "")); | role2 role3 |
---|
ну и завершающий аккорд - "инвертирование" списка t4, оставляя только те роли из списка roles, которые не попали в t4
result := @Unique(@Replace(roles; t4; "")); | role1 |
---|
UPD: Формулу можно сократить и привести к следующей:
t0:=users*+"~"*+roles;
t1:=@Replace(t0; list; "");
t2:=@Unique(@Right(t1;"~"));
result := @Trim(@Unique(@Replace(roles; t2; "")));
result
Комментариев нет:
Отправить комментарий