【问题标题】:Querying from IMDB Database using MySQL [closed]使用 MySQL 从 IMDB 数据库查询 [关闭]
【发布时间】:2021-01-25 20:39:48
【问题描述】:

我写了一个 SQL 查询来回答以下问题:

在 IMBD 数据库中查找所有与 Yash Chopra 合作的电影比任何其他导演都多的演员。

示例架构:

person
(pid *
,name
);

m_cast
(mid *
,pid *
);

m_director
(mid*
,pid*
);

* = (component of) PRIMARY KEY

以下是我的查询:

WITH common_actors AS 
        (SELECT A.actor_id as actors, B.director_id as director_id, B.movies as movies_with_director,
        B.director_id as yash_chops_id, B.movies as movies_with_yash_chops FROM
        (SELECT M_Cast.PID as actor_id, M_Director.PID as director_id, COUNT(*) as movies from M_Cast
        left join M_Director  
        ON M_Cast.MID = M_Director.MID
        GROUP BY actor_id, director_id) A
        JOIN
        (SELECT M_Cast.PID as actor_id, M_Director.PID as director_id, COUNT(*) as movies from M_Cast
        left join M_Director  
        ON M_Cast.MID = M_Director.MID
        GROUP BY actor_id, director_id
        )B
        ON A.actor_id = B.actor_id
        WHERE B.director_id in (SELECT PID FROM Person WHERE Name LIKE 
        '%Yash%Chopra%'))

SELECT distinct actors as actor_id, movies_with_yash_chops as total_movies FROM common_actors
    WHERE actors NOT IN (SELECT actors FROM common_actors WHERE movies_with_director > movies_with_yash_chops)

并且由此获得的结果是长度:430 行。然而,获得的结果应该是 243 行的长度。谁能建议我在查询中出错的地方?我的方法对吗?

示例结果:

    Actor name
  0 Sharib Hashmi
  1 Kulbir Badesron
  2 Gurdas Maan
  3 Parikshat Sahni
...
242 Ramlal Shyamlal

提前致谢!

【问题讨论】:

    标签: mysql imdb


    【解决方案1】:

    考虑以下几点:

    DROP TABLE IF EXISTS person;
    
    CREATE TABLE person
    (person_id SERIAL PRIMARY KEY
    ,name VARCHAR(20) NOT NULL UNIQUE
    );
    
    DROP TABLE IF EXISTS movie;
    
    CREATE TABLE movie
    (movie_id SERIAL PRIMARY KEY
    ,title VARCHAR(50) NOT NULL UNIQUE
    );
    
    DROP TABLE IF EXISTS m_cast;
    
    CREATE TABLE m_cast
    (movie_id INT NOT NULL
    ,person_id INT NOT NULL
    ,PRIMARY KEY(movie_id,person_id)
    );
    
    DROP TABLE IF EXISTS m_director;
    
    CREATE TABLE m_director
    (movie_id INT NOT NULL
    ,person_id INT NOT NULL
    ,PRIMARY KEY(movie_id,person_id)
    );
    
    INSERT INTO person (name) VALUES
    ('Steven Feelberg'),
    ('Manly Kubrick'),
    ('Alfred Spatchcock'),
    ('Fred Pitt'),
    ('Raphael DiMaggio'),
    ('Bill Smith');
    
    INSERT INTO movie VALUES
    (1,'Feelberg\'s Movie with Fred & Raph'),
    (2,'Feelberg and Fred Ride Again'),
    (3,'Kubrick shoots DiMaggio'),
    (4,'Kubrick\'s Movie with Bill Smith'),
    (5,'Spatchcock Presents Bill Smith');
    
    INSERT INTO m_director VALUES
    (1,1),
    (2,1),
    (3,2),
    (4,2),
    (5,3);
    
    INSERT INTO m_cast VALUES
    (1,4),
    (1,5),
    (2,4),
    (3,5),
    (4,6),
    (5,6);
    

    我包含电影表只是为了方便参考。它与实际问题无关。 另请注意,此模型假定演员仅列出一次,无论他们是否在给定电影中担任多个角色。

    以下查询询问“每个演员和导演多久合作一次”...

    演员是任何电影的演员。 导演是任何电影导演的人。

    SELECT a.name actor
         , d.name director
         , COUNT(DISTINCT ma.movie_id) total
      FROM person d
      JOIN m_director md 
        ON md.person_id = d.person_id
      JOIN person a
      LEFT
      JOIN m_cast ma 
        ON ma.person_id = a.person_id
       AND ma.movie_id = md.movie_id
      JOIN m_cast x
        ON x.person_id = a.person_id
     GROUP
        BY actor
         , director;
         
    +-------------------+-------------------+-------+
    | actor             | director          | total |
    +-------------------+-------------------+-------+
    | Fred Pitt         | Alfred Spatchcock |     0 |
    | Fred Pitt         | Manly Kubrick     |     0 |
    | Fred Pitt         | Steven Feelberg   |     2 |
    | Raphael DiMaggio  | Alfred Spatchcock |     0 |
    | Raphael DiMaggio  | Manly Kubrick     |     1 |
    | Raphael DiMaggio  | Steven Feelberg   |     1 |
    | Bill Smith        | Alfred Spatchcock |     1 |
    | Bill Smith        | Manly Kubrick     |     1 |
    | Bill Smith        | Steven Feelberg   |     0 |
    +-------------------+-------------------+-------+
    

    通过观察,我们可以看到:

    • 唯一一位比其他导演更常与菲尔伯格合作的演员是弗雷德·普里特
    • 拉斐尔·迪卡普里奥和比尔·史密斯都与两位导演(尽管是不同的导演)合作频繁

    编辑:虽然我并没有认真提倡将此作为解决方案,但以下只是为了证明上面提供的内核确实是您解决问题所需要的一切......

    SELECT x.*
      FROM 
         ( SELECT a.* 
     FROM 
        ( SELECT a.name actor
               , d.name director
               , COUNT(DISTINCT ma.movie_id) total
            FROM person d
            JOIN m_director md 
              ON md.person_id = d.person_id
            JOIN person a
            LEFT
            JOIN m_cast ma 
              ON ma.person_id = a.person_id
             AND ma.movie_id = md.movie_id
            JOIN m_cast x
              ON x.person_id = a.person_id
           GROUP
              BY actor
               , director
        ) a
     LEFT
     JOIN
        ( SELECT a.name actor
               , d.name director
               , COUNT(DISTINCT ma.movie_id) total
            FROM person d
            JOIN m_director md 
              ON md.person_id = d.person_id
            JOIN person a
            LEFT
            JOIN m_cast ma 
              ON ma.person_id = a.person_id
             AND ma.movie_id = md.movie_id
            JOIN m_cast x
              ON x.person_id = a.person_id
           GROUP
              BY actor
               , director
        ) b
       ON b.actor = a.actor
      AND b.director <> a.director 
      AND b.total > a.total
    WHERE b.actor IS NULL
    ) x
    LEFT JOIN
         ( SELECT a.* 
     FROM 
        ( SELECT a.name actor
               , d.name director
               , COUNT(DISTINCT ma.movie_id) total
            FROM person d
            JOIN m_director md 
              ON md.person_id = d.person_id
            JOIN person a
            LEFT
            JOIN m_cast ma 
              ON ma.person_id = a.person_id
             AND ma.movie_id = md.movie_id
            JOIN m_cast x
              ON x.person_id = a.person_id
           GROUP
              BY actor
               , director
        ) a
     LEFT
     JOIN
        ( SELECT a.name actor
               , d.name director
               , COUNT(DISTINCT ma.movie_id) total
            FROM person d
            JOIN m_director md 
              ON md.person_id = d.person_id
            JOIN person a
            LEFT
            JOIN m_cast ma 
              ON ma.person_id = a.person_id
             AND ma.movie_id = md.movie_id
            JOIN m_cast x
              ON x.person_id = a.person_id
           GROUP
              BY actor
               , director
        ) b
       ON b.actor = a.actor
      AND b.director <> a.director 
      AND b.total > a.total
    WHERE b.actor IS NULL
    ) y
    ON y.actor = x.actor AND y.director <> x.director
    WHERE y.actor IS NULL;
    
    +-----------+-----------------+-------+
    | actor     | director        | total |
    +-----------+-----------------+-------+
    | Fred Pitt | Steven Feelberg |     2 |
    +-----------+-----------------+-------+
    

    这会返回每个演员的列表,以及他们最常合作的导演。在这种情况下,由于 Bill Smith 和 Raphael DiMaggio 与两位导演合作的次数最多,因此他们被排除在结果之外。

    您的问题的答案是简单地从该列表中选择 Yash Chopra 列为主管的所有行。

    【讨论】:

    • 嘿,谢谢你的回复,但是如果你看到我写的查询,我已经想出了每个可能的演员-导演组合以及他们的电影总数,问题是我实际上是对如何真正找到与某个导演合作的电影比其他任何导演都多的演员感到困惑。就我而言,我自己加入了这个表,条件是右表只有那个导演,这样我就可以得到所有与其他导演一起制作更多电影的演员并将他们过滤掉,因此剩下的演员将是我们的答案(我的查询)
    • 啊我明白了!非常感谢您抽出时间来回答这个问题。
    • 我如何接受这个答案(对不起,我很笨),但我确实赞成!
    猜你喜欢
    • 1970-01-01
    • 2011-11-06
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    • 2012-09-02
    • 2015-02-26
    相关资源
    最近更新 更多