我有以下表格:
表:user_groups(多对多)
表:profile_groups(多对多)
基本上,我想编写一个sql脚本来找出为每个用户分配的配置文件。
所以最后应该只有两列:user_id
和profile_id
。
我将如何做到这一点?
编辑:它实际上比简单的连接复杂得多。
E.g。
User_groups可能包含以下行
和profile_groups可能包含以下内容:
所以结果应该是
每个用户应该只有一个个人资料
答案 0 :(得分:4)
前几天我刚看到这样的问题。我认为这里的难点在于您正在寻找user_id / profile_id组合,其中user_id具有profile_id具有的每个group_id,不多也不少。因此,采用通常的连接并添加一些相关性来计算每个配置文件/用户拥有的group_id的数量,并确保它们匹配(已经编辑了几次):
select user_id, profile_id
from user_groups join profile_groups on
user_groups.group_id=profile_groups.group_id
group by user_id, profile_id
having count(user_groups.group_id) =
(select count(*) from profile_groups as pg where
pg.profile_id=profile_groups.profile_id)
and count(profile_groups.group_id) = (select count(*) from user_groups as ug where
ug.user_id=user_groups.user_id)
;
这是一个包含两个配置文件的运行,每个配置文件包含三个组,其中一个公共组和第四个配置文件中的新用户:
sqlite> create table user_groups (user_id integer, group_id varchar);
sqlite> create table profile_groups (profile_id integer, group_id varchar);
sqlite> insert into user_groups values(1, 'group1');
sqlite> insert into user_groups values(1, 'group2');
sqlite> insert into user_groups values(1, 'group3');
sqlite> insert into user_groups values(2, 'group1');
sqlite> insert into user_groups values(2, 'group2');
sqlite> insert into user_groups values(3, 'group4');
sqlite> insert into user_groups values(4, 'group1');
sqlite> insert into user_groups values(4, 'group5');
sqlite> insert into user_groups values(4, 'group6');
sqlite>
sqlite> insert into profile_groups values (11, 'group1');
sqlite> insert into profile_groups values (11, 'group2');
sqlite> insert into profile_groups values (11, 'group3');
sqlite>
sqlite> insert into profile_groups values (21, 'group1');
sqlite> insert into profile_groups values (21, 'group2');
sqlite>
sqlite> insert into profile_groups values (22, 'group4');
sqlite>
sqlite> insert into profile_groups values (23, 'group1');
sqlite> insert into profile_groups values (23, 'group5');
sqlite> insert into profile_groups values (23, 'group6');
sqlite> select user_id, profile_id
...> from user_groups join profile_groups on
...> user_groups.group_id=profile_groups.group_id
...> group by user_id, profile_id
...> having count(user_groups.group_id) =
...> (select count(*) from profile_groups as pg where
...> pg.profile_id=profile_groups.profile_id)
...> and count(profile_groups.group_id) = (select count(*) from user_groups as ug where
...> ug.user_id=user_groups.user_id)
...> ;
1|11
2|21
3|22
4|23
答案 1 :(得分:2)
SELECT ug.user_id, pg.profile_id
FROM user_groups AS ug
LEFT JOIN profile_groups AS pg
ON ug.group_id = pg.group_id
答案 2 :(得分:1)
这将显示与个人资料相关联的用户列表:
SELECT ug.user_id,
pg.profile_id
FROM USER_GROUPS ug
JOIN PROFILE_GROUPS pg ON pg.group_id = ug.group_id
...虽然这将返回可能与个人资料相关联的所有用户的列表。如果不是,则profile_id
列将为null
:
SELECT ug.user_id,
pg.profile_id
FROM USER_GROUPS ug
LEFT JOIN PROFILE_GROUPS pg ON pg.group_id = ug.group_id
请记住,由于关系是一个user_id到多个配置文件,user_id
可能会多次显示,并且可能会重复。对于非重复的数据列表,请添加DISTINCT子句或定义GROUP BY子句。 IE:
SELECT DISTINCT
ug.user_id,
pg.profile_id
FROM USER_GROUPS ug
LEFT JOIN PROFILE_GROUPS pg ON pg.group_id = ug.group_id
SELECT ug.user_id,
pg.profile_id
FROM USER_GROUPS ug
LEFT JOIN PROFILE_GROUPS pg ON pg.group_id = ug.group_id
GROUP BY ug.user_id, pg.profile_id
答案 3 :(得分:0)
jjia6395,从zzzeek的回答下面的评论判断,你想使用ALL
运算符。
顺便说一下,你的问题非常不清楚,编辑没有帮助。