我有三个表:
Users { id | name | email }
User_Group { User_id | group_id }
Subscriptions {user_id, sub_level }
可以将用户登录到更多该用户组。
用户可以订阅的不仅仅是订阅计划。
假设我们有:
表用户:
[1, John, [email protected]]
[2, Lara, [email protected]]
表用户组:
[1,6] // User 1 is assigned to Group 6
[1,3] // User 1 also assigned to Group 3
[2,3] // User 2 in ONLY assigned to Group 3
表格订阅:
[1, 8] // User 1 have subscription level 8
[2, 8] // User 2 have subscription level 8
[2, 9] // Also User 2 have subscription level 9
我想要得到的是:
分配给仅组3且具有至少一个订阅的所有UNIQUE用户。
我尝试过的
SELECT U.Username, U.email, G.group_id, S.sub_level FROM `Users` AS U
INNER JOIN `User_Group` AS G
ON U.id = G.user_id
INNER JOIN `Subscriptions` AS S
ON U.id = S.user_id
WHERE G.group_id = 3
Limit 0,10
问题是它将显示也分配给其他组的用户,例如组1和6中的用户1。另外,由于一个用户可以具有许多订阅级别,因此它还会显示重复的行。
最佳答案
一种方法是使用聚合:
SELECT U.Username, U.email, MAX(G.group_id)
FROM `Users` U INNER JOIN
`User_Group` G
ON U.id = G.user_id INNER JOIN
`Subscriptions` S
ON U.id = S.user_id
GROUP BY U.Username, U.email
HAVING MAX(G.group_id) = 3 AND MIN(G.group_id) = 3 ; -- condition on groups
订阅条件仅由
join
条件处理。这可能更有效,因为:
select u.*
from users u
where exists (select 1
from user_groups ug
where ug.user_id = u.id and ug.group_id = 3
) and
not exists (select 1
from user_groups ug
where ug.user_id = u.id and ug.group_id <> 3
) and
exists (select 1
from subscriptions s
where s.user_id = u.id
);
对于此查询,您需要在
user_groups(user_id, group_id)
和subscriptions(user_id)
上建立索引。实际上,对于制定查询的两种方式,这些索引都是一个好主意。