我有以下数据库模型:
CREATE TABLE IF NOT EXISTS account (
name VARCHAR PRIMARY KEY,
parent INTEGER REFERENCES account(name) ON UPDATE CASCADE ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS permission (
name VARCHAR PRIMARY KEY
);
CREATE TABLE IF NOT EXISTS account_permission (
account VARCHAR NOT NULL REFERENCES account(name) ON UPDATE CASCADE ON DELETE CASCADE,
permission VARCHAR NOT NULL REFERENCES permission(name) ON UPDATE CASCADE ON DELETE CASCADE
);
DELETE FROM account;
DELETE FROM permission;
DELETE FROM account_permission;
INSERT INTO account(name) VALUES('a1');
INSERT INTO account(name) VALUES('a2');
INSERT INTO account(name, parent) VALUES('a3', 'a1');
INSERT INTO permission(name) VALUES('dummy');
INSERT INTO permission(name) VALUES('edit');
INSERT INTO permission(name) VALUES('delete');
INSERT INTO account_permission(account, permission) VALUES('a1', 'dummy');
INSERT INTO account_permission(account, permission) VALUES('a2', 'edit');
INSERT INTO account_permission(account, permission) VALUES('a3', 'delete');
我想要的是一个查询,它返回所有具有权限的帐户及其从父帐户继承的权限。在这种情况下,我希望得到这样的结果:
帐户|许可
a1 |虚拟
a2 |编辑
a3 |虚拟
a3 |删除
a1和a2并不特别,但我不知道如何编写递归查询以包含具有所有父权限和自己权限的a3。任何帮助表示赞赏。
答案 0 :(得分:1)
P.S。
你应该重新设计表格
帐户应具有ID和NAME
许可应该有一个ID和一个名称
表格应通过ID连接。
迭代查询返回帐户和祖先(包括自我)的元组
+---------+----------+
| account | ancestor |
+---------+----------+
| a1 | a1 |
+---------+----------+
| a2 | a2 |
+---------+----------+
| a3 | a1 |
+---------+----------+
| a3 | a3 |
+---------+----------+
查询的其余部分用于将每个帐户的祖先与其权限进行匹配并删除冗余。
with t
as
(
select name as account
,name as ancestor
from account
-- where name = ... /* for a specific account */
union all
select t.account
,a.parent as ancestor
from t
join account as a
on a.name = t.ancestor
where a.parent is not null
)
select distinct
t.account
,ap.permission
from t
join account_permission as ap
on ap.account = t.ancestor
order by t.account
,ap.permission
;
答案 1 :(得分:0)
您还需要一个查询,它可以获取父权限并可以与union合并。这是
select * from account_permission
union
select a.name, ap.permission from account_permission ap, account a where a.parent = ap.account