使用MySQL从IMDB数据库查询

问题描述

我编写了一个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,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

谢谢!

解决方法

请考虑以下内容:

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)
);

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),3);

INSERT INTO m_cast VALUES
(1,4),(1,5),6),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 |
+-------------------+-------------------+-------+

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

  • 弗雷德·普里特(Fred Pritt)是与费尔伯格一起工作次数最多的唯一演员
  • 拉斐尔·迪卡普里奥(Raphael DiCaprio)和比尔·史密斯(Bill Smith)经常与两名董事(尽管董事不同)共同工作

编辑:虽然我没有认真地倡导将其作为解决方案,但以下内容只是为了证明上述提供的内核确实是解决问题所需要的...

SELECT x.*
  FROM 
     ( SELECT a.* 
 FROM 
    ( SELECT a.name actor,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,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,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 |
+-----------+-----------------+-------+

这将返回每个演员的名单,以及与他们最常合作的导演。在这种情况下,由于比尔·史密斯和拉斐尔·迪马吉奥最经常与两位董事平等地合作,因此他们被排除在结果之外。

您的问题的答案只是从列表中选择列出Yash Chopra作为主管的所有行。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...