SQL查询问题:多表ID匹配筛选与用户偏好电影筛选
没问题,这两个都是SQL开发里很常见的需求,我来给你一步步拆解解决:
问题1:查询某表中与另一表匹配数量满足至少对应要求的所有ID
假设我们有两个关联表,比如users(存储用户ID)和orders(存储用户订单,通过user_id关联),需求是找出至少有N个订单的用户ID。核心思路是通过分组统计匹配记录的数量,再用HAVING子句过滤符合数量要求的结果。
举个具体例子,要找至少有3个订单的用户ID:
SELECT u.id FROM users u JOIN orders o ON u.id = o.user_id GROUP BY u.id HAVING COUNT(o.order_id) >= 3;
如果不需要关联原表(比如直接从关联表统计),也可以简化成:
SELECT user_id FROM orders GROUP BY user_id HAVING COUNT(*) >= 3;
逻辑说明:
GROUP BY按目标ID分组,把同ID的所有关联记录归为一组COUNT()统计每组内的匹配记录数量HAVING过滤出数量达标分组,最终得到符合要求的ID
问题2:查询仅包含用户偏好类型的电影
这个需求的核心是确保电影的所有类型都属于用户的偏好集合,不能有超出偏好的类型(比如用户偏好sci-fi、action、romance,带horror的电影直接排除,只有全属于这三类的电影才返回)。
假设表结构:
users:id(用户ID)users_genres:user_id(关联用户)、genre_id(用户偏好类型ID)movies:id(电影ID)、title(电影名)等movie_genres:movie_id(关联电影)、genre_id(电影类型ID)
这里提供两种常用实现方式:
方法1:用NOT EXISTS排除不符合的电影
逻辑直观:找到所有电影,不存在任何一个不属于用户偏好的类型。
-- 假设要查询的用户ID是123 SELECT m.id, m.title FROM movies m WHERE NOT EXISTS ( SELECT 1 FROM movie_genres mg WHERE mg.movie_id = m.id AND mg.genre_id NOT IN ( SELECT ug.genre_id FROM users_genres ug WHERE ug.user_id = 123 ) );
方法2:用分组统计验证所有类型都匹配
思路是统计电影的总类型数,以及和用户偏好匹配的类型数,如果两者相等,说明电影的所有类型都在偏好里:
SELECT m.id, m.title FROM movies m JOIN movie_genres mg ON m.id = mg.movie_id LEFT JOIN users_genres ug ON mg.genre_id = ug.genre_id AND ug.user_id = 123 GROUP BY m.id, m.title HAVING COUNT(mg.genre_id) = COUNT(ug.genre_id);
逻辑说明:
- 先关联电影和它的所有类型
- 左连接用户的偏好类型,只有匹配的类型才会有
ug.genre_id的值 - 分组后,
COUNT(mg.genre_id)是电影的总类型数,COUNT(ug.genre_id)是匹配偏好的类型数 - 当两者相等时,说明电影没有任何类型超出用户偏好,符合要求
内容的提问来源于stack exchange,提问作者user126440




