Это работает с базой данных Oracle, поэтому оно должно работать или приближать вас к SQL Server, поскольку я знаю, что SQL Server поддерживает основной компонент этого, операцию CASE.
CREATE TABLE user_permissions (
user_role VARCHAR2(10) NOT NULL,
dir VARCHAR2(10) NOT NULL,
user_access VARCHAR2(5) NOT NULL
);
INSERT INTO user_permissions VALUES ('admin', 'dir1', 'allow');
INSERT INTO user_permissions VALUES ('admin', 'dir2', 'allow');
INSERT INTO user_permissions VALUES ('power', 'dir1', 'allow'); -- Allow and Deny dir1
INSERT INTO user_permissions VALUES ('power', 'dir1', 'deny');
INSERT INTO user_permissions VALUES ('power', 'dir2', 'deny');
COMMIT;
SELECT UNIQUE j.*
FROM (
SELECT user_role, dir,
MAX(CASE user_access WHEN 'allow' THEN 1 ELSE 0 END) allowFlag,
MAX(CASE user_access WHEN 'deny' THEN 1 ELSE 0 END) denyFlag
FROM user_permissions
GROUP BY user_role, dir
) t
JOIN user_permissions j ON (t.user_role = j.user_role AND t.dir = j.dir)
WHERE j.user_access = 'allow' OR (t.allowFlag = 0 and user_access = 'deny');
Результаты:
USER_ROLE DIR USER_ACCESS
---------- ---------- -----------
admin dir1 allow
admin dir2 allow
power dir1 allow
power dir2 deny
По сути, вы используете сводную таблицу, чтобы объединить несколько строк в одну строку, описывающую атрибуты каталога.Получив объединенную строку, легко сравнить объявленные вами атрибуты, чтобы объединить строки, которые вы хотите отобразить.