在多对多的关系中选择匹配的子集[英] Selecting matching subset in many-to-many relation

本文是小编为大家收集整理的关于在多对多的关系中选择匹配的子集的处理方法,想解了在多对多的关系中选择匹配的子集的问题怎么解决?在多对多的关系中选择匹配的子集问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

假设我在用户和项目之间存在多对多关系:一个用户可能属于多个项目,一个项目可能有多个用户.此关系编码在表 user_projects:

create table user_projects
(
proj_id int references projs(id) not null,
user_id int references users(id) not null,
primary key (proj_id, user_id)
);

这是我的问题:给定一组用户(user1、user2、...),我想选择给定用户集是其所有用户子集的所有项目.

例如,如果我在下面插入数据,然后询问用户 1 和 2 的所有项目,那么查询应该只返回项目 1.

insert into user_projects values (1, 1);
insert into user_projects values (1, 2);
insert into user_projects values (1, 3);
insert into user_projects values (2, 1);
insert into user_projects values (2, 3);

(我使用的是 PostgreSQL,如果最好的解决方案恰好是非标准的.)

编辑:为澄清起见,用户集应被解释为对要返回的项目列表的约束.集合 {u1, u2} 意味着项目列表应该只包括那些至少有用户 u1 和 u2 的项目;集合 {u1} 表示应返回至少具有用户 u1 的所有项目,作为限制情况,空集表示应返回 所有 个项目.

推荐答案

Select project_ID 
from user_projects
where user_ID in (1,2)
group by project_ID
Having count(*) = 2

您知道您有 2 个用户,您知道他们将是唯一的(主键)所以你知道如果有 2 条记录,对于同一个项目,那么它就是你想要的.

您的问题表明您已发送 GIVEN 用户,因此您知道哪些用户以及有多少用户.上面的 SQL 可以更新为接受这些已知的参数,因此保持动态,不仅限于 2 个用户.

where user_ID in (userlist)
having count(*) = (cntuserList)

-----------处理用户集为空的情况-----

Select P.project_ID 
from Projects P
LEFT JOIN user_projects UP
where (UP.user_ID in (1,2) OR UP.USER_ID is null)
group by project_ID
Having count(*) = 2

这就是它的作用.它返回所有项目,如果有用户附属于该项目,它会识别它们.如果您设置包含用户,则返回的项目列表由该集合过滤,确保整个集合在项目中通过have子句.

如果集合为空,则 LEFT join 以及 userID 为 null 语句将保留没有列出用户的项目,无论集合是否为空.have 子句将进一步减少集合到您在集合中定义的用户数,或 0 表示返回所有未分配用户的项目.

我们尚未讨论的另一个极端情况是,如果项目包含的用户数超过您在集合中定义的用户数,会发生什么情况.目前该项目将被退回;但我不肯定这就是你想要的.

顺便说一句,感谢您让我思考.我不再深入研究代码了.这就是为什么我不时来这里看看我能不能帮忙的原因!

本文地址:https://www.itbaoku.cn/post/1764140.html