多对多关联场景中,筛选满足修改时间条件的影片的最优查询方案
筛选满足关联表或关联实体时间条件的影片
你有如下多对多关联结构:
Movie — MovieActor — Actor id id id role name movie_id modified_at actor_id modified_at
需要找出所有满足MovieActor.modified_at 或 Actor.modified_at 大于指定日期的影片,原有的UNION方案确实可以实现,但不够简洁,这里提供两种更优雅的实现方式:
方案一:关联三表+OR条件+去重
通过一次关联三个表,直接用OR条件过滤满足任一时间要求的记录,最后用DISTINCT去重避免同一影片多次输出:
SELECT DISTINCT m.id FROM Movie m JOIN MovieActor ma ON m.id = ma.movie_id JOIN Actor a ON ma.actor_id = a.id WHERE ma.modified_at > 'your_target_timestamp' OR a.modified_at > 'your_target_timestamp';
说明:
- 使用
JOIN而非LEFT JOIN,因为只有存在关联的MovieActor和Actor记录时,才可能满足时间条件,INNER JOIN能过滤掉无关联的影片,更符合需求。 DISTINCT用于消除同一影片对应多条满足条件的关联记录时的重复输出。
方案二:EXISTS子查询
利用EXISTS子查询判断影片是否存在符合条件的关联记录,逻辑更直观,且无需额外去重:
SELECT m.id FROM Movie m WHERE EXISTS ( SELECT 1 FROM MovieActor ma JOIN Actor a ON ma.actor_id = a.id WHERE ma.movie_id = m.id AND (ma.modified_at > 'your_target_timestamp' OR a.modified_at > 'your_target_timestamp') );
说明:
- 子查询会检查当前影片是否存在满足时间条件的关联关系,只要存在就会返回该影片ID,每个影片只会被返回一次,无需
DISTINCT。 - 若
MovieActor.movie_id、MovieActor.modified_at、Actor.modified_at字段建有索引,该方案的查询性能会更优。
对比原方案
原方案的UNION ALL会返回重复的影片ID,若改用UNION去重则会触发排序操作,性能不如上述两种方案;而新方案将逻辑集中在一个查询中,可读性和维护性更强。
内容的提问来源于stack exchange,提问作者bizzz
相关产品推荐
相关产品推荐

