架构
Movie(title, year, director, budget, earnings)
Actor(stagename, realname, birthyear)
ActedIn(stagename, title, year, pay)
CanWorkWith(stagename, director)
我需要找到从未在电影中获利的所有演员(舞台名称和真实姓名)(收入>预算)。所以找到所有不好的演员:P
SELECT A.stagename, A.realname
FROM Actor A
WHERE A.stagename NOT IN
(SELECT B.stagename
FROM ActedIN B
WHERE EXIST
(SELECT *
FROM Movie M
WHERE M.earnings > M.budget AND M.title = B.title AND M.year))
这会找到其stagename没有出现在第二个查询中的所有actor吗?第二个查询将找到在电影中起作用的所有舞台名称。
这是对的吗?
答案 0 :(得分:2)
我认为你可以稍微简化一下,见下文:
SELECT DISTINCT A.stagename, A.realname
FROM Actor A
WHERE NOT EXISTS
(SELECT *
FROM Actor B
, Movie M
, ActedIn X
WHERE M.Title = X.Title
AND X.StageName = B.StageName
AND M.earnings > M.budget
AND M.year = X.Year
AND A.StageName = B.StageName)
答案 1 :(得分:0)
是的,你有正确的想法使用NOT IN
,但你在第二个子查询的WHERE
子句中缺少半个布尔条件。我想你打算用AND M.year = B.year
WHERE M.earnings > M.budget AND M.title = B.title AND M.year = B.year
您也可以使用几个LEFT JOIN
来执行此操作,在联接的右侧查找NULL
。这可能比子查询更快。
SELECT
A.stagename,
A.realname
FROM Actor A
LEFT OUTER JOIN ActedIN B ON A.stagename = B.stagename
LEFT OUTER JOIN Movie M ON B.title = M.title AND B.year = M.year AND M.earnings > M.budget
WHERE
/* NULL ActedIN.stagename indicates the actor wasn't in this movie */
B.stagename IS NULL
答案 2 :(得分:0)
这样可行,但只是在ActedIn和Movie之间进行连接而不是存在。
外连接可能也比NOT IN子句更快,但你需要运行解释计划才能确定。
答案 3 :(得分:0)
那就行了。你也可以这样写:
SELECT A.stagename, A.realname, SUM(B.pay) AS totalpay
FROM Actor A
INNER JOIN ActedIn B ON B.stagename = A.stagename
LEFT JOIN Movie M ON M.title = B.title AND M.year = B.year AND M.earnings > M.budget
WHERE M.title IS NULL
GROUP BY A.stagename, A.realname
ORDER BY totalpay DESC
它基本上取得了盈利的电影并将其用作左连接条件;当左连接为空时,它会被计算。
我还添加了所有不良演员的总薪酬,并将他们从最佳到最差付费排名; - )
答案 4 :(得分:0)
SELECT
a.stagename,
a.realname
FROM
Actor a
LEFT JOIN
ActedIn b ON a.stagename = b.stagename
LEFT JOIN
Movie c ON b.title = c.title
AND a.year = b.year
AND c.earnings >= c.budget
WHERE
c.title IS NULL
GROUP BY
a.stagename,
a.realname
- 无子查询
- 从未参加过电影演员的演员
- 如果需要,可以访问聚合函数。