我有一个有关电影信息的数据库。在我的应用程序中,我有很多用于这些电影的滤镜。例如,用户可以选择一些流派和国家/地区,应用程序应返回所有具有这些流派和国家/地区的电影。
我写了一些SQL,它可以工作。我的问题有更好的解决方案吗?
SELECT m.*
FROM movies m
WHERE m.id IN (
SELECT groupped_movies.id
FROM (
SELECT m.id,
array_agg(mc.country_code) country_codes,
array_agg(mg.genre_id) genre_ids
FROM movies m
LEFT JOIN movie_countries mc on m.id = mc.movie_id
LEFT JOIN movie_genres mg on m.id = mg.movie_id
GROUP BY m.id
) groupped_movies
WHERE groupped_movies.country_codes @> ARRAY ['ru', 'ja'] AND groupped_movies.genre_ids @> ARRAY [1, 2, 3])
答案 0 :(得分:1)
您的代码在Postgres中可能工作正常。但我会想到更多类似的东西:
SELECT m.*
FROM movies m
WHERE EXISTS (SELECT mc.movie_id
FROM movie_countries mc
WHERE m.id = mc.movie_id AND
mc.country_code IN ('ru', 'ja')
GROUP BY mc.movie_id
HAVING COUNT(*) = 2
) AND
EXISTS (SELECT mg.movie_id
FROM movie_genres mg
WHERE m.id = mg.movie_id AND
mc.country_code IN (1, 2, 3)
GROUP BY mc.movie_id
HAVING COUNT(*) = 3
)
至少,这避免了笛卡尔积,因此它应该具有更好的性能。