我有一个表,其中包含所有的报告
report_id | Name
---------------+-------------
1 | Sales Q3
2 | Sales Q2
字符串
我有一个关系表,其中包含一个到多个关系的报告与部门
report_id | dept_id
-----------------+---------------
1 | 4
1 | 5
2 | 4
型
关系表表示报告(1)包含有关部门(4 & 5)的数据,报告(2)包含有关部门(4)的数据
我有另一个表,它指定了用户和部门之间的关系。
user_id | dept_id
-----------------+---------------
1 | 4
1 | 5
2 | 4
3 | 5
型
用户表还表示用户和部门之间的关系。
我需要获取一个特定用户的所有报告集,只有当用户在该特定报告中的所有部门。
例如
用户(1)有权访问dept(4,5),因此查询应返回两个报告(1,2)
用户(2)有权访问部门(4),因此查询应仅返回报告(2),而不应返回报告(1),因为它与部门(5)有关
用户(3)有权访问部门(5),因此查询不应返回任何报告,因为报告与部门(4)相关
类似于
Select * from reports inner join relation on relation.report_id = reports.report_id ( some condition to satisfy all rows of relations.dept_id are present in users.dept_id table ) where users.user_id = 1
型
考虑到上述用例,这些表是维护报表、部门和用户之间关系的正确方法吗?
编辑:
添加了架构定义
Postgres 9.5版
CREATE TABLE reports (
report_id integer NOT NULL,
report_name varchar(100)
);
CREATE TABLE relation (
report_id integer NOT NULL,
dept_id integer NOT NULL
);
CREATE TABLE users (
user_id integer NOT NULL,
dept_id integer NOT NULL
);
INSERT INTO reports VALUES(1, 'Sales Q3'),(2, 'Sales Q2');
INSERT INTO relation VALUES(1, 4),(1, 5),(2,4);
INSERT INTO users VALUES(1, 4),(1, 5),(2,4),(3,5);
型
3条答案
按热度按时间k3fezbri1#
我们可以在
COUNT()
作为窗口函数的帮助下尝试join方法:字符串
上面的想法是,我们尝试为每个用户的部门找到一个匹配的报告。如果所有部门都匹配一个报告,我们将返回给定用户的所有报告。
d4so4syb2#
用数组实现的情况下.
创建了用户可以访问的dept_id数组,并将报告中的dept_id转换为数组。
如果用户部门数组完全存在于报告部门数组中,请确定。
字符串
wsxa1bj13#
字符串
fiddle
基于几个假设,这个问题没有公开。比如:所有涉及的列都定义为
NOT NULL
。为了获得最佳性能,在
relation(dept_id, report_id)
上设置一个索引**,在relation(report_id, dept_id)
上设置一个**索引(另一列在前)。两者之一可以是PK,另一个是额外的普通索引。请参阅我的小提琴中的索引!请参阅:你后来发布了一个类似问题的答案-可以优化:
型
fiddle的
我的第一个查询应该对大表执行得更好,因为它可以提前排除大多数不相关的报告,而您的查询必须处理 * 所有 * 报告。