我有五个表:
用户
user_id | name
--------------------
0 | Mark
1 | Jen
2 | Mbali
3 | Mbabani
4 | Fang Zhao
作用
role_id | name
--------------------
3 | Employee
4 | Customer Asia
5 | Customer Africa
User_Role_Assoc
role_id | user_id
--------------------
3 | 0
3 | 1
3 | 2
5 | 3
4 | 4
Role_Reps
role_id | user_id
--------------------
4 | 0
4 | 1
请求
req_id | user_id
--------------------
8 | 3
9 | 3
10 | 4
11 | 4
Mark、Jen 和 Mbali 都是一家虚构公司的员工 (role_id=3)。另外两个用户 Mbabani 和方召是创建请求的客户。
查询应该能够看到 req_id 8 和 9 是由属于 Customer Africa 角色(通过 User_Role_Assoc)的用户 (Mbabani[3]) 请求的,该角色没有分配代表 (Role_Reps)。
查询应该能够看到 req_id 10 和 11 是由属于 Customer Asia 角色(通过 User_Role_Assoc)的用户(Fang Zhao[4])请求的,该角色确实有代表。
所有员工都应该能够看到所有请求。除非在 Role_Reps 表中为该角色分配了角色代表。如果有任何代表,在本例中为 Mark 和 Jen,则他们是唯一有权查看请求的人。如果 Role_Reps 表中没有定义任何代表,那么每个人都应该能够看到请求。
所以我需要一个查询:
如果我传入 userid=2
(Mbali),我应该得到以下结果:
req_id | user_id
--------------------
10 | 4
11 | 4
如果我传入 userid=0
或 userid=1
(Mark 或 Jen),我应该得到以下结果:
req_id | user_id
--------------------
8 | 3
9 | 3
10 | 4
11 | 4
我希望我已经说清楚了。
更新
以下是使用数据生成表格的 DDL:
DROP TABLE IF EXISTS t_user;
CREATE TABLE t_user (
userid integer PRIMARY KEY,
name varchar(20)
);
GRANT ALL PRIVILEGES ON t_user TO PUBLIC;
INSERT INTO t_user (userid, name) VALUES (0,'Mark');
INSERT INTO t_user (userid, name) VALUES (1,'Jen');
INSERT INTO t_user (userid, name) VALUES (2,'Mbali');
INSERT INTO t_user (userid, name) VALUES (3,'Mbabani');
INSERT INTO t_user (userid, name) VALUES (4,'Fang Zhao');
DROP TABLE IF EXISTS t_role;
CREATE TABLE t_role (
roleid integer PRIMARY KEY,
name varchar(20)
);
GRANT ALL PRIVILEGES ON t_role TO PUBLIC;
INSERT INTO t_role (roleid, name) VALUES (3,'Employee');
INSERT INTO t_role (roleid, name) VALUES (4,'Customer Asia');
INSERT INTO t_role (roleid, name) VALUES (5,'Customer Africa');
DROP TABLE IF EXISTS t_user_role_assoc;
CREATE TABLE t_user_role_assoc (
roleid integer,
userid integer,
primary key(roleid, userid)
);
GRANT ALL PRIVILEGES ON t_user_role_assoc TO PUBLIC;
INSERT INTO t_user_role_assoc (roleid, userid) VALUES (3,0);
INSERT INTO t_user_role_assoc (roleid, userid) VALUES (3,1);
INSERT INTO t_user_role_assoc (roleid, userid) VALUES (3,2);
INSERT INTO t_user_role_assoc (roleid, userid) VALUES (5,3);
INSERT INTO t_user_role_assoc (roleid, userid) VALUES (4,4);
DROP TABLE IF EXISTS t_role_reps;
CREATE TABLE t_role_reps (
roleid integer,
userid integer,
primary key(roleid, userid)
);
GRANT ALL PRIVILEGES ON t_role_reps TO PUBLIC;
INSERT INTO t_role_reps (roleid, userid) VALUES (4,0);
INSERT INTO t_role_reps (roleid, userid) VALUES (4,1);
DROP TABLE IF EXISTS t_request;
CREATE TABLE t_request (
req_id integer PRIMARY KEY,
userid integer
);
GRANT ALL PRIVILEGES ON t_request TO PUBLIC;
INSERT INTO t_request (req_id, userid) VALUES (8,3);
INSERT INTO t_request (req_id, userid) VALUES (9,3);
INSERT INTO t_request (req_id, userid) VALUES (10,4);
INSERT INTO t_request (req_id, userid) VALUES (11,4);
最佳答案
正如一般建议,我发现通过使用自然键而不是代理项建立一组新关系通常更容易了解发生了什么。所以在这种情况下,我可能会这样做:
User
-------------------------
username | name
-------------------------
mark | Mark
jen | Jen
mbali | Mbali
mbabani | Mbabani
fangzhao | Fang Zhao
Role
------------------------------------
role_id | name
------------------------------------
employee | Employee
customer_asia | Customer Asia
customer_africa | Customer Africa
User_Role_Assoc
------------------------------
role_id | user_id
------------------------------
employee | mark
employee | jen
employee | mbali
customer_africa | mbabani
customer_asia | fangzhao
Role_Reps
----------------------------
role_id | user_id
----------------------------
customer_asia | mark
customer_africa | jen
Request
---------------------
req_id | user_id
---------------------
8 | mbabani
9 | mbabani
10 | fangzhao
11 | fangzhao
现在,当您开始构建查询时,您不必一次完成所有连接,您可以交互式地添加一个又一个连接,并且随着您越来越接近您的需要,它对您来说会更加清晰。完成后,您可以将该查询直接带回您的实际数据库,其中包含所有内容的代理 ID,它将“正常工作”。
关于您的实际问题,您指望没有触发其他事物存在的事物。我通常发现这种东西很难用 SQL 表达。您可能会发现,如果您向其中一个关系添加额外数据以表示某些内容是公共(public)的或全局的,并执行受限查询 UNION
并使用单独的查询来获取所有全局内容,您可能会发现它更容易。 p>
关于sql - 如何正确构造此 sql 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9119470/