我如何简化这个PostgreSQL查询(通过连接表过滤)

问题描述 投票:2回答:1

假设我有一个角色(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%')
sql postgresql
1个回答
0
投票

在一个查询中它将是这样的(不能在没有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
© www.soinside.com 2019 - 2024. All rights reserved.