【问题标题】:Finding rows in the same table which have the same many-to-many relationships as given other row在同一个表中查找与给定其他行具有相同多对多关系的行
【发布时间】:2011-07-25 06:47:28
【问题描述】:

以下是表结构。

  • tbl_movie_master (movie_id,title)
  • tbl_genre_master (genre_id,genre)
  • tbl_movie_genre (movie_id,genre_id)

一部电影可以映射多种流派,所以tbl_movie_genre的情况下存在多对多关系。

我有电影详细信息页面,我在其中获取电影 ID。我必须编写查询来完成以下任务。

我必须找到与给定电影 ID 匹配的所有类型的电影。

例如我有电影 ID 45,这部电影属于喜剧和浪漫类型,然后我必须找到所有其他类型为喜剧和浪漫的电影。不应填充只有喜剧或只有爱情的电影。

是否可以在单个查询中完成?

更新:

在以下示例中,只有前 2 部电影满足条件。 “Hum tum ke pyar”和“housefull”。

drop table if exists tbl_movie_master, tbl_genre_master, tbl_movie_genre ;

create table tbl_movie_master (movie_id int, title varchar(100));
insert into tbl_movie_master values (1, 'Hum tum ke pyar'), (2, 'housefull'), (3, 'ek vakta ke liye'), (4, 'chalo pyar kare');

create table tbl_genre_master (genre_id int, genre varchar(100));
insert into tbl_genre_master values (1, 'horror'), (2, 'remoance'), (3, 'suspense'), (4, 'social');

create table tbl_movie_genre (movie_id int, genre_id int);
insert into tbl_movie_genre values (1, 1), (1, 2), (2, 1), (2, 2), (3, 3), (4, 1), (4,4);

mysql> select * from tbl_movie_master;
+----------+------------------+
| movie_id | title            |
+----------+------------------+
|        1 | Hum tum ke pyar  | 
|        2 | housefull        | 
|        3 | ek vakta ke liye | 
|        4 | chalo pyar kare  | 
+----------+------------------+
4 rows in set (0.00 sec)

mysql> select * from tbl_genre_master;
+----------+----------+
| genre_id | genre    |
+----------+----------+
|        1 | horror   | 
|        2 | remoance | 
|        3 | suspense | 
|        4 | social   | 
+----------+----------+
4 rows in set (0.00 sec)

mysql> select * from tbl_movie_genre;
+----------+----------+
| movie_id | genre_id |
+----------+----------+
|        1 |        1 | 
|        1 |        2 | 
|        2 |        1 | 
|        2 |        2 | 
|        3 |        3 | 
|        4 |        1 | 
|        4 |        4 | 
+----------+----------+
7 rows in set (0.00 sec)


SELECT m.*
FROM tbl_movie_master m
JOIN tbl_movie_genre mg ON mg.movie_id = m.movie_id
WHERE mg.genre_id = ALL (SELECT mg.genre_id FROM tbl_movie_genre mg WHERE mg.movie_id = 1);

Empty set (0.00 sec)

SELECT m.title 
FROM tbl_movie_master m
JOIN tbl_movie_genre allgenres 
  ON m.movie_id= allgenres.movie_id
JOIN 
  (SELECT genre_id FROM tbl_movie_genre WHERE movie_id=1) somegenres
  ON somegenres.genre_id=allgenres.genre_id;

+-----------------+
| title           |
+-----------------+
| Hum tum ke pyar | 
| Hum tum ke pyar | 
| housefull       | 
| housefull       | 
| chalo pyar kare | 
+-----------------+
5 rows in set (0.00 sec)

SELECT  M.`title`, G.`genre`, M2.`title`
FROM    tbl_movie_master AS M, tbl_movie_genre AS A
LEFT JOIN tbl_movie_master AS M2 ON A.`movie_id` = M2.`movie_id`
LEFT JOIN tbl_genre_master AS G ON A.`genre_id` = G.`genre_id`
WHERE   M.`movie_id` = 1;

+-----------------+----------+------------------+
| title           | genre    | title            |
+-----------------+----------+------------------+
| Hum tum ke pyar | horror   | Hum tum ke pyar  | 
| Hum tum ke pyar | remoance | Hum tum ke pyar  | 
| Hum tum ke pyar | horror   | housefull        | 
| Hum tum ke pyar | remoance | housefull        | 
| Hum tum ke pyar | suspense | ek vakta ke liye | 
| Hum tum ke pyar | horror   | chalo pyar kare  | 
| Hum tum ke pyar | social   | chalo pyar kare  | 
+-----------------+----------+------------------+
7 rows in set (0.00 sec)

【问题讨论】:

    标签: mysql


    【解决方案1】:

    尝试:

    SELECT m.title 
    FROM tbl_movie_master m
    JOIN tbl_movie_genre allgenres 
      ON m.movie_id= allgenres.movie_id
    JOIN 
      (SELECT genre_id FROM tbl_movie_genre WHERE movie_id=45) somegenres
      ON somegenres.genre_id=allgenres.genre_id;
    

    【讨论】:

    • 我想知道您和my approach之间是否存在性能差异。
    • @Alp:好问题。我希望这与表的索引方式以及tbl_movie_genre 中有多少行有关。
    【解决方案2】:
    SELECT m.*
    FROM movie m
    JOIN movie_genre mg ON mg.movie_id = m.id
    WHERE mg.id = ALL (SELECT mg.genre_id FROM movie_genre mg WHERE mg.movie_id = ?)
    

    ? 是给定的电影ID

    【讨论】:

    【解决方案3】:

    这个问题需要 JOIN。

    这样的事情会起作用:

    SELECT  M.`title`, G.`genre`, M2.`title`
    FROM    tbl_movie_master AS M, tbl_movie_genre AS A
    LEFT JOIN tbl_movie_master AS M2 ON A.`movie_id` = M2.`movie_id`
    LEFT JOIN tbl_genre_master AS G ON A.`genre_id` = G.`genre_id`
    WHERE   M.`movie_id` = A.`movie_id`
                AND M.`title` = "Your Movie";
    

    【讨论】:

    • 这不是正确的答案,问题是检索与给定电影具有完全相同类型的所有电影的查询
    • 这正是查询返回的内容。为了使结果更清楚一点,我在 SELECT-Part 中添加了原始标题和流派,以显示链接是哪种流派。编辑:有一个错误,在 Where-Statement 中缺少链接 M.movie_id = A.movie_id
    【解决方案4】:

    需要在 dnagirl 的答案中添加“group by having”以获得完全相同数量的类别。我想这就是我要找的……

    SELECT mg1.movie_id,
           mm1.title,
           COUNT(*) AS cnt
    FROM   tbl_movie_genre AS mg1
           INNER JOIN tbl_movie_master AS mm1
             ON mg1.movie_id = mm1.movie_id
           INNER JOIN (SELECT genre_id
                       FROM   tbl_movie_genre
                       WHERE  movie_id = 1) AS tt1
             ON mg1.genre_id = tt1.genre_id
    GROUP  BY movie_id
    HAVING cnt = (SELECT COUNT(*) AS mycnt
                  FROM   tbl_movie_genre
                  WHERE  movie_id = 1); 
    

    【讨论】:

    • 如果此方法有效,而其他方法无效,您应该接受(您自己的)答案。
    猜你喜欢
    • 2016-12-26
    • 1970-01-01
    • 1970-01-01
    • 2018-06-07
    • 2019-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多