mysql - User、User_Group 和 Subscriptions 表之间的高级内部联接

标签 mysql sql database select inner-join

我有三个表:

Users          { id | name | email }
User_Group     { User_id | group_id }
Subscriptions  {user_id, sub_level }
  • 用户可以注册到更多的用户组。
  • 用户可以订阅多个订阅计划。

假设我们有:

表用户:

[1, John, john@email.com]

[2, Lara, lara@email.com]

表用户组:

[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

问题是它会显示也分配给其他组的用户,例如组 6 和组 3 中的用户 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) 上建立索引。实际上,这些索引对于制定查询的两种方式都是一个好主意。

关于mysql - User、User_Group 和 Subscriptions 表之间的高级内部联接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34754011/

相关文章:

php - Drupal 大量查询

mysql - COALESCE 与 SUM 与 Join 表的计算不正确

python - pyQT 和 MySQL 或 MSSQL 连接

mysql - 如何选择帖子及其所有相关帖子?

mysql - 在数据库表中的旧记录之后插入一条新记录

java - 删除 SQLite DB 表中的最后一个元素

php - Postgres/PHP - 检索插入行 ID 的标准方法是什么?

ElasticSearch中的Mysql等价物,根据字段更新字段

mysql - 为每个客户选择前 3 项

sql - 使用临时列过滤结果