我试图回答sqlzoo.net上的问题#12 (http://sqlzoo.net/wiki/More_JOIN_operations)。我无法自己找出答案,但我确实设法在网上找到答案。
12:约翰特拉沃尔塔的最繁忙的年份,展示了他每年制作超过2部电影的年份和电影数量。答案:
SELECT yr,COUNT(title) FROM
movie JOIN casting ON movie.id=movieid
JOIN actor ON actorid=actor.id
WHERE name='John Travolta'
GROUP BY yr
HAVING COUNT(title)=(SELECT MAX(c) FROM
(SELECT yr,COUNT(title) AS c FROM
movie JOIN casting ON movie.id=movieid
JOIN actor ON actorid=actor.id
WHERE name='John Travolta'
GROUP BY yr) AS t)
我不完全理解的部分之一是多连接:
FROM movie
JOIN casting ON movie.id=movieid
JOIN actor ON actorid=actor.id
我不完全理解的另一部分是:
(SELECT yr,COUNT(title) AS c FROM
movie JOIN casting ON movie.id=movieid
JOIN actor ON actorid=actor.id
WHERE name='John Travolta'
GROUP BY yr) AS t)
3。上面的代码试图找到什么?
答案 0 :(得分:0)
正确的答案是:
SELECT yr, COUNT(title)
FROM movie m
JOIN casting c ON m.id=c.movieid JOIN actor a ON c.actorid=a.id
WHERE name='John Travolta'
GROUP BY yr
HAVING COUNT(title) > 2;
你找到的答案(这似乎是sqlzoo网站上的一个错误)正在寻找任何一年的计数等于最高计数的年份。
我在上面的查询中使用了表别名来清除表的连接方式。电影加入了铸造,铸造加入了演员。
让您感到困惑的子查询每年都会列出,以及约翰特拉沃尔塔明星那一年的电影数量。如果您以书面形式回答问题,则不需要它。
关于学习资源,请确保您掌握了基础知识。了解http://w3schools.com/sql处的所有内容。当你准备好了更多时,尝试在你最喜欢的搜索引擎中搜索“sql join multiple tables”。
答案 1 :(得分:0)
好的,很高兴你不要害怕,我会尽力帮助澄清发生的事情......请原谅我将查询重新格式化为写作查询的心态。它更好地展示了事物来源的关系(我的观点),也可以帮助你。
关于我的重写的一些其他事情。我还想使用对表的别名引用,以便每个列都使用它所源自的表(或别名)进行限定。它可以防止歧义,尤其是对于不了解表结构和表之间关系的人。 (m =电影的别名,c =投射的别名,a =演员表的别名)。对于子查询,并保持别名混淆清晰,我用2加上后缀,如m2,c2,a2。
SELECT
m.yr,
COUNT(m.title)
FROM
movie m
JOIN casting c
ON m.id = c.movieid
JOIN actor a
ON c.actorid = a.id
WHERE
a.name = 'John Travolta'
GROUP BY
m.yr
HAVING
COUNT(m.title) = ( SELECT MAX(t.movieCount)
FROM
( SELECT m2.yr,
COUNT(m2.title) AS movieCount
FROM
movie m2
JOIN casting c2
ON m2.id = c2.movieid
JOIN actor a2
ON c2.actorid = a2.id
WHERE
a2.name='John Travolta'
GROUP BY
m2.yr ) AS t
)
首先,查看最外面的查询(别名m,c,a),最里面的查询(别名m2,c2,a2)实际上是相同的。
查询必须首先从最深的查询运行...在这种情况下是m2,c2,a2查询。看看它,看看它将提供什么。如果你运行它,你每年都会得到一部电影和电影的数量......他们的样本数据的起始结果从1976年一直到2010年。到目前为止,没有任何复杂的东西(大约20行)。现在,由于每个表都可能有一个别名,每个子查询(例如这个必须有一个别名,所以这就是“as t”。所以,没有真正的表,它包装整个查询的结果集并分配这是别名“t”。
所以现在,在查询中提高一级也包含在parens ......
SELECT MAX(t.movieCount)
FROM (EntireSubquery as t)
虽然缩写,但这就是引擎正在做的事情。查看子查询结果,给出别名“t”并找到最大“movieCount”值,该值是给定年份内完成的电影数量。在这种情况下,实际数字是3,我们差不多完成了。
现在,对于最外层的查询......再次,这几乎与最里面的查询相同。唯一的区别是HAVING子句。在执行每年的所有分组之后应用此选项。然后它将每年的IT行结果集计数与SELECT MAX的3值结果进行比较(t.movieCount)......
因此,所有只有1或2部电影的年份都被排除在结果之外,只有一年有3部电影被包括在内。
现在,澄清一下JOIN。每个表应该与一个或多个表有关系(也称为链接表,例如同时具有电影和演员/演员的演员表。因此,请考虑连接,如何将表按顺序排列,以便每个人都能碰到另一个,直到我把它们全部链接在一起。在这种情况下
电影 - >通过电影ID链接的转换,然后是Casting - >演员身份角色扮演者,这就是我在视觉上分层次地做的...我从电影表开始,根据电影ID =演员电影ID加入演员表。现在,从Casting表加入到基于公共Actor ID字段的Actor表
FROM
movie m
JOIN casting c
ON m.id = c.movieid
JOIN actor a
ON c.actorid = a.id
现在,这是一个简单的关系,但是你可以有一个包含多个子级表的主表。您可以根据相应的数据连接多个表。非常简单的样本澄清了这一点。你有一张学生桌去学校。学生拥有学位专业,种族,地址状态(假设在线学校,学生可以来自任何州)。如果您有关于度,种族和状态的查找表,您可能会想出类似......
的内容select
s.firstname,
s.lastname,
d.DegreeDescription,
e.ethnicityDescription,
st.stateName
from
students s
join degrees d
on s.degreemajor = d.degreeID
join ethnicity e
on s.ethnicityID = e.id
join states st
on s.homeState = st.stateID
请注意每个表在学生的表下直接关联的层次结构表示。并非所有表都需要比最后一个表更深。
所以,那里有很多网站,比如Mark提供的w3schools,但是学会一次解剖小块...从A点到Z点的最小表是什么?画出关系。然后,根据您正在寻找的要求标准去掉。