假设我有一个角色(hasMany)的电影关系。
我想通过角色名称和电影标题来过滤我的结果。所以我想要返回所有名字都像'Sam'的角色,这个角色必须至少有一部电影,其中电影的标题就像'Sam the Movie'。我仍然希望将所有电影都与角色相关联。
我只是想知道是否有更好的方法来做到这一点?是否可以在一个查询中获取它?
WITH t1 AS
(SELECT c.id, c.name, array_agg(m.title) AS movie_titles FROM characters c
LEFT JOIN characters_movies cm ON cm.character_id = c.id
LEFT JOIN movies m ON m.id = cm.movie_id
WHERE c.name LIKE '%Sam%'
GROUP BY c.id)
SELECT * FROM t1 WHERE exists
(SELECT * FROM unnest(movie_titles) AS title
WHERE name LIKE '%Sam the Movie%')
在一个查询中它将是这样的(不能在没有ddl的情况下进行测试)。请注意我是如何使用不同的别名加入电影两次的。与m
的加入确保您在标题上匹配。第二个am
是获得所有头衔。我很确定使用LEFT JOIN
不需要得到你想要的结果所以我使用了普通的JOIN
,它往往效率更高。
SELECT c.id, c.name, array_agg(am.title) AS movie_titles
FROM characters c
JOIN characters_movies cm ON cm.character_id = c.id
JOIN movies m ON (m.id = cm.movie_id AND m.name LIKE '%Sam the Movie%')
JOIN characters_movies acm ON acm.character_id = c.id
JOIN movies am ON (am.id = acm.movie_id)
WHERE c.name LIKE '%Sam%'
GROUP BY c.id