使用 IMDB 数据集查找所有与 Yash Chopra 合作制作的电影比任何其他导演都多的演员(转贴)
Find all the actors that made more movies with Yash Chopra than any other director using IMDB dataset (Reposted)
第一个查询 q1 给出了期望的结果。
但是查询 q2 给出了一对演员和导演的电影数量过多。
SELECT * FROM
(SELECT pc.PID AS actorID, pc.Name AS Actor, pd.PID AS directorID,pd.Name AS
Director,COUNT(DISTINCT m.MID) count_movie FROM Movie m
JOIN
M_Cast mc ON m.MID = Trim(mc.MID)
JOIN
M_Director md ON m.MID = md.MID
JOIN
Person pc ON Trim(mc.PID) = pc.PID
JOIN
Person pd ON md.PID = pd.PID
WHERE pd.Name LIKE '%Yash%' GROUP BY pc.Name) AS q1
JOIN
(SELECT pc.PID AS actorID,pc.Name Actor,pd.PID AS directorID,pd.Name AS Director, COUNT(DISTINCT
m.MID) count_movie FROM Movie m
JOIN
M_Cast mc ON m.MID = TRIM(mc.MID )
JOIN
M_Director md ON m.MID = md.MID
JOIN
Person pc ON TRIM(mc.PID) = pc.PID
JOIN
Person pd ON md.PID = pd.PID
WHERE pd.Name NOT LIKE '%Yash%' GROUP BY pc.PID) AS q2
ON q1.Actor = q2.Actor ORDER BY q1.count_movie DESC
actorID Actor directorID Director count_movie actorID Actor directorID Director count_movie
0 nm0707271 Jagdish Raj nm0007181 Yash Chopra 11 nm0707271 Jagdish Raj nm0474806 Gulshan Kumar 98
1 nm0471443 Manmohan nm0007181 Yash Chopra 10 nm0471443 Manmohan nm0695153 T. Prakash Rao 39
2 nm0407002 Iftekhar nm0007181 Yash Chopra 9 nm0407002 Iftekhar nm1065099 C.P. Dixit 93
3 nm0534501 Madan Puri nm0007181 Yash Chopra 8 nm0534501 Madan Puri nm0619050 Hiren Nag 94
最右边的 movie_count 似乎高得离谱。如果必须匹配答案,第一行应该小于 11。
这里我没有使用上面的WHERE条件只是为了说明我的查询哪里错了。
即使我使用 Where 条件
where q1.count_movie > q2.count_movie
我得到的结果是
Name count
0 Sanjeev Kumar 3
1 Sanjeev Kumar 3
2 Sanjeev Kumar 3
3 Sanjeev Kumar 3
4 Ashok Kumar 2
下面的输出是正确的结果。
它将给出 245 行。我只显示了 6 行。
Name count
0 Jagdish Raj 11
1 Manmohan 10
2 Iftekhar 9
3 Shashi Kapoor 7
4 Rakhee Gulzar 5
5 Waheeda Rehman 5
给出的表格是
- 电影(中,标题,年份)
- M_Cast(MID,PID)
- 人物(PID、姓名、性别)
- M_Director(MID,PID)
我是sql的新人,在调试代码时遇到了很多麻烦。
请帮助我理解逻辑。
查询第二部分的问题是您汇总了所有其他导演的所有电影,而不是计算每个导演的电影。
我看到了两种完成任务的方法:
- 每位演员将 Yash Chopra 的电影数量与所有其他演员进行比较。 (这需要
WHERE yash_chopra_count > ANY (...)
,但 SQLite 没有 ANY
关键字。)或者将 Yash Chopra 的电影数量与其他人的最大电影数量进行比较。 (这在 SQLite 中有效。)
- 按电影数量对每个演员的导演进行排名,看看排名最好的演员是否是 Yash Chopra。 (应该用
ROW_COUNT
完成)。
在我们开始之前,让我们检查一下,如果我们做对了一切:数据模型允许每部电影有多个导演。但我们仍然可以数数。如果一个演员和 Yash Chopra 一起拍了三部电影,和 I. S. Johar 拍了三部电影,我们不在乎这些是六部独立的电影还是可能只有三部电影,而 Yash Chopra 是 I. S. Johar 的助理导演。在我的演员示例中,我们看到另一位导演的电影数量至少与 Yash Chopra 一样多,所以我们不想 select 这个演员。 m:n 关系因此没有障碍。没什么区别。
既然我们已经确定可以简单地计算每个演员和导演的电影数量,让我们看看这两种方法:
将 Yash Chopra 计数与其他最大计数进行比较
如前所述,我们必须聚合其他控制器两次(一次用于每个控制器的计数,一次用于最大计数),因为 SQLite 缺少 ANY
运算符。不过,当我们使用 CTE 来提高可读性时,这并不是什么大问题。
with director_actor as
(
select
c.pid as pid_actor,
d.pid as pid_director,
count(*) as movie_count
from m_director d
join m_cast c on c.mid = d.mid
group by c.pid, d.pid
)
select pid_actor, movie_count
from director_actor
where pid_director = (select pid from person where name = 'Yash Chopra')
and movie_count >
(
select coalesce(max(movie_count), 0)
from director_actor other
where other.pid_actor = director_actor.pid_actor
and other.pid_director <> director_actor.pid_director
);
按电影数量对每个演员的导演进行排名
我们必须采取哪些步骤才能找到有问题的演员?
- 计算每个演员和导演的电影数量。
- 按演员对导演进行排名。大多数电影的导演排名第一。如果有平局,那么我们将另一位导演排在 Yash Chopra 之后,因此如果 Yash Chopra 的电影比其他导演多,他只会排名第一。
- 保留最佳导演是 Yash Chopra 的演员。
对于排名,我会使用 ROW_NUMBER
。
with ranked as
(
select
c.pid as pid_actor,
d.pid as pid_director,
yc.pid as pid_yash_chopra,
count(*) as movie_count,
row_number() over (partition by c.pid order by count(*) desc, d.pid = yc.pid) as rn
from m_director d
join m_cast c on c.mid = d.mid
left join person yc on yc.pid = d.pid and name = 'Yash Chopra'
group by c.pid, d.pid, yc.pid
)
select pid_actor, movie_count
from ranked
where rn = 1 and pid_director = pid_yash_chopra;
第一个查询 q1 给出了期望的结果。 但是查询 q2 给出了一对演员和导演的电影数量过多。
SELECT * FROM
(SELECT pc.PID AS actorID, pc.Name AS Actor, pd.PID AS directorID,pd.Name AS
Director,COUNT(DISTINCT m.MID) count_movie FROM Movie m
JOIN
M_Cast mc ON m.MID = Trim(mc.MID)
JOIN
M_Director md ON m.MID = md.MID
JOIN
Person pc ON Trim(mc.PID) = pc.PID
JOIN
Person pd ON md.PID = pd.PID
WHERE pd.Name LIKE '%Yash%' GROUP BY pc.Name) AS q1
JOIN
(SELECT pc.PID AS actorID,pc.Name Actor,pd.PID AS directorID,pd.Name AS Director, COUNT(DISTINCT
m.MID) count_movie FROM Movie m
JOIN
M_Cast mc ON m.MID = TRIM(mc.MID )
JOIN
M_Director md ON m.MID = md.MID
JOIN
Person pc ON TRIM(mc.PID) = pc.PID
JOIN
Person pd ON md.PID = pd.PID
WHERE pd.Name NOT LIKE '%Yash%' GROUP BY pc.PID) AS q2
ON q1.Actor = q2.Actor ORDER BY q1.count_movie DESC
actorID Actor directorID Director count_movie actorID Actor directorID Director count_movie
0 nm0707271 Jagdish Raj nm0007181 Yash Chopra 11 nm0707271 Jagdish Raj nm0474806 Gulshan Kumar 98
1 nm0471443 Manmohan nm0007181 Yash Chopra 10 nm0471443 Manmohan nm0695153 T. Prakash Rao 39
2 nm0407002 Iftekhar nm0007181 Yash Chopra 9 nm0407002 Iftekhar nm1065099 C.P. Dixit 93
3 nm0534501 Madan Puri nm0007181 Yash Chopra 8 nm0534501 Madan Puri nm0619050 Hiren Nag 94
最右边的 movie_count 似乎高得离谱。如果必须匹配答案,第一行应该小于 11。
这里我没有使用上面的WHERE条件只是为了说明我的查询哪里错了。 即使我使用 Where 条件
where q1.count_movie > q2.count_movie
我得到的结果是
Name count
0 Sanjeev Kumar 3
1 Sanjeev Kumar 3
2 Sanjeev Kumar 3
3 Sanjeev Kumar 3
4 Ashok Kumar 2
下面的输出是正确的结果。 它将给出 245 行。我只显示了 6 行。
Name count
0 Jagdish Raj 11
1 Manmohan 10
2 Iftekhar 9
3 Shashi Kapoor 7
4 Rakhee Gulzar 5
5 Waheeda Rehman 5
给出的表格是
- 电影(中,标题,年份)
- M_Cast(MID,PID)
- 人物(PID、姓名、性别)
- M_Director(MID,PID)
我是sql的新人,在调试代码时遇到了很多麻烦。 请帮助我理解逻辑。
查询第二部分的问题是您汇总了所有其他导演的所有电影,而不是计算每个导演的电影。
我看到了两种完成任务的方法:
- 每位演员将 Yash Chopra 的电影数量与所有其他演员进行比较。 (这需要
WHERE yash_chopra_count > ANY (...)
,但 SQLite 没有ANY
关键字。)或者将 Yash Chopra 的电影数量与其他人的最大电影数量进行比较。 (这在 SQLite 中有效。) - 按电影数量对每个演员的导演进行排名,看看排名最好的演员是否是 Yash Chopra。 (应该用
ROW_COUNT
完成)。
在我们开始之前,让我们检查一下,如果我们做对了一切:数据模型允许每部电影有多个导演。但我们仍然可以数数。如果一个演员和 Yash Chopra 一起拍了三部电影,和 I. S. Johar 拍了三部电影,我们不在乎这些是六部独立的电影还是可能只有三部电影,而 Yash Chopra 是 I. S. Johar 的助理导演。在我的演员示例中,我们看到另一位导演的电影数量至少与 Yash Chopra 一样多,所以我们不想 select 这个演员。 m:n 关系因此没有障碍。没什么区别。
既然我们已经确定可以简单地计算每个演员和导演的电影数量,让我们看看这两种方法:
将 Yash Chopra 计数与其他最大计数进行比较
如前所述,我们必须聚合其他控制器两次(一次用于每个控制器的计数,一次用于最大计数),因为 SQLite 缺少 ANY
运算符。不过,当我们使用 CTE 来提高可读性时,这并不是什么大问题。
with director_actor as
(
select
c.pid as pid_actor,
d.pid as pid_director,
count(*) as movie_count
from m_director d
join m_cast c on c.mid = d.mid
group by c.pid, d.pid
)
select pid_actor, movie_count
from director_actor
where pid_director = (select pid from person where name = 'Yash Chopra')
and movie_count >
(
select coalesce(max(movie_count), 0)
from director_actor other
where other.pid_actor = director_actor.pid_actor
and other.pid_director <> director_actor.pid_director
);
按电影数量对每个演员的导演进行排名
我们必须采取哪些步骤才能找到有问题的演员?
- 计算每个演员和导演的电影数量。
- 按演员对导演进行排名。大多数电影的导演排名第一。如果有平局,那么我们将另一位导演排在 Yash Chopra 之后,因此如果 Yash Chopra 的电影比其他导演多,他只会排名第一。
- 保留最佳导演是 Yash Chopra 的演员。
对于排名,我会使用 ROW_NUMBER
。
with ranked as
(
select
c.pid as pid_actor,
d.pid as pid_director,
yc.pid as pid_yash_chopra,
count(*) as movie_count,
row_number() over (partition by c.pid order by count(*) desc, d.pid = yc.pid) as rn
from m_director d
join m_cast c on c.mid = d.mid
left join person yc on yc.pid = d.pid and name = 'Yash Chopra'
group by c.pid, d.pid, yc.pid
)
select pid_actor, movie_count
from ranked
where rn = 1 and pid_director = pid_yash_chopra;