AngularFire2 > Firestore:含`in`/`not in`的复杂查询及待评分电影查询实现
查询用户待评分电影的SQL方案
嘿,这个需求很典型!要找出某个用户还没评分的电影,核心就是筛选出所有电影里,该用户没在Stars表留下评分记录的那些。下面给你几种实用的SQL写法,适配不同的数据库场景:
方法1:使用NOT EXISTS(推荐,效率较高)
这种方式在大多数数据库里性能表现都不错,尤其是当Stars表有(userId, movieId)联合索引的时候。
SELECT m.uid, m.title FROM Movies m WHERE NOT EXISTS ( SELECT 1 FROM Stars s WHERE s.movieId = m.uid AND s.userId = 123 -- 替换成你要查询的目标用户ID );
逻辑很直白:每遍历一部电影,就检查该用户有没有对应的评分记录,没有就把这部电影纳入结果。
方法2:LEFT JOIN + IS NULL(逻辑直观)
这种写法更容易理解,适合刚接触这类查询的开发者:
SELECT m.uid, m.title FROM Movies m LEFT JOIN Stars s ON m.uid = s.movieId AND s.userId = 123 -- 替换成目标用户ID WHERE s.movieId IS NULL;
我们把Movies和Stars按电影ID+用户ID做左连接,这样所有电影都会被保留——已经评分的电影会有对应的Stars数据,没评分的电影对应的Stars字段全是NULL,过滤出这些NULL记录就是待评分的电影。
方法3:使用NOT IN(注意数据限制)
如果你的Stars表中userId不会出现NULL值,这种写法也能用:
SELECT m.uid, m.title FROM Movies m WHERE m.uid NOT IN ( SELECT s.movieId FROM Stars s WHERE s.userId = 123 -- 替换成目标用户ID );
先查出该用户已经评分过的所有电影ID,再从Movies里排除这些ID,剩下的就是待评分的内容。
小提示
如果你的数据量较大,记得给Stars表建立(userId, movieId)的联合索引,能大幅提升这些查询的执行速度哦!
内容的提问来源于stack exchange,提问作者Rogério R. Alcântara




