此SQL查询是否有更有效的替代方法?

时间:2020-02-05 16:40:34

标签: sql postgresql

我正在处理电影数据集,该数据集具有电影,流派和桥表in_genre的表。 以下查询尝试查找两部电影之间的共同体裁。我先进行两次连接以获取类型列表,然后进行相交以找到常见的类型。 有没有更有效的方法?

表架构:

  • 电影:movie_id(PK)(int)
  • in_genre(bridge_table):movie_id(FK)(int),genre_id(int)
SELECT count(*) as common_genre 
FROM(
    // getting genres of first movie
    SELECT in_genre.genre_id
    FROM movie INNER JOIN in_genre ON movie.id = in_genre.movie_id
    WHERE movie.id = 0109830

    INTERSECT

    // getting genres of second movie
    SELECT in_genre.genre_id
    FROM movie INNER JOIN in_genre ON movie.id = in_genre.movie_id
    WHERE movie.id = 1375666
) as genres

2 个答案:

答案 0 :(得分:1)

如果仅需要来自in_genre的数据,则无需加入movie表。

您可以使用EXISTS查找常见类型。

SELECT COUNT(DISTINCT genre_id) as common_genre
FROM in_genre ig
WHERE movie_id = 0109830
  AND EXISTS 
  (
      SELECT 1
      FROM in_genre ig2
      WHERE ig2.movie_id = 1375666
        AND ig2.genre_id = ig.genre_id
  )

答案 1 :(得分:1)

如果您想要流派,我会简单地做:

SELECT genre_id as common_genre
FROM in_genre ig
WHERE movie_id IN (0109830, 1375666)
GROUP BY genre_id
HAVING COUNT(*) = 2;

如果要计数,则子查询非常简单:

SELECT COUNT(*)
FROM (SELECT genre_id as common_genre
      FROM in_genre ig
      WHERE movie_id IN (0109830, 1375666)
      GROUP BY genre_id
      HAVING COUNT(*) = 2
     ) g;

如果您想要有关类型的完整信息,那么我建议exists

select g.*
from genres g
where exists (select 1
              from in_genre ig
              where ig.genre_id = g.genre_id and ig.movie_id = 0109830
             ) and
      exists (select 1
              from in_genre ig
              where ig.genre_id = g.genre_id and ig.movie_id = 1375666
             );