¶前言
有雨的时候既没有太阳也没有月亮,人们却多不以为许。
有雨的夜晚则另有一番月夜所没有的韵味。
有时不由让人想起李商隐“何当共剪西窗烛,却话巴山夜雨时”的名句
雨中, 从对面天空中传来丝丝音符; 这里, 静谧而又舒畅.
¶说明
本文算作一篇译文吧, 题目来自于卡内基.梅隆大学的数据库技术课程的Homework, 在数据库postgresql中亲测通过; 各版本的SQL环境差别不大, 看看下文就知道, 在其他版本的数据库, 如mysql | sqlite等都能通过.
这部分主要是使用SQL语句进行查询相关操作, 涉及到sql的视图, 索引等, 本文提供英文原版和中文版.
¶题目详述
在本页面中, 你需要使用SQL的查询语句来回答下面的问题, 下文中给出的是一个关于电影的数据库, 该数据库中包含电影影片和演员的信息, 数据表如下所示:
- movies(mid, title, year, num ratings, rating) , 主键: mid
- play in(mid, name, cast_position), 主键: mid, name
这两张表包含如下信息: 哪个演员出演哪部电影, 以及在电影中位置; 对于每一部电影, 都包含title(标题), year(上映时间), num ratings(收到的评分数目), rating(以及这些评分的平均值, 是一个float型的数字, 在0~10之间, 10代表’’excellent’').
请在你的机器上使用PostgreSQL, 根据以上信息回答如下问题:
Question 1: 热身练习 . . . . . . . . . . . . . . . . . . . . . . . . . [5 points]
(a) [2 分] 打印出所有在电影"Quantum of Solace"中的所有演员, 按照他们 在影片中的位置(cast position)排列, 且只打印出他们的名字(name);
(b) [3 分] 打印2002年上映的所有影片的标题, 约束rating评分大于8, 且num_ratings > 1.
Question 2: 找出相关明星的电影. . . . . . . . . . . . . . . . . . . . [5 points]
(a) [5 分] 打印有关电影明星"Sean Connery"主演(即, 他在演员表位于第一位: cast_position=1)的影片的标题, 电影标题按字母排序.
Question 3: 最优秀的演员 . . . . . . . . . . . . . . . . . . . . . . . . . . [15 points]
(a) [8 分] 我们想要查找最优秀的演员. 关于最优秀的定义如下计算公式:
请打印最优秀的5个演员, 先后顺序与演员名字字母顺序无关.
(b) [7 分] 现在, 我们想要找到5个最优秀的演员, 仅就他们获得评分的数量而言. 如, 如果演员‘Smith’在两部电影中出演, 且两部影片的评分分别是10和15, 则Smith’s 流行度为25 (=10+15).
请根据演员的流行度打印出最流行的5个演员. 同样, 先后顺序与演员名字字母顺序无关.
Question 4: 最受争议的演员 . . . . . . . . . . . . . . . . [10 points]
(a) [10 分] 我们想要找出最受争议的演员.最受争议的演员的计算方式如下: 通过演员在两部影片中获得评分的最大差异来评判(与演员在演员表的位置无关). 如, 演员‘Smith’在一部电影中获得的评分rating=1.2, 在另一部电影中获得的评分rating=9.5, 那么他所获得的争议得分为9.5-1.2= 8.3.
请打印出最具争议性的演员的姓名, 同样, 先后顺序与演员名字字母顺序无关.
Question 5: 仆从人员 . . . . . . . . . . . . . . . . . . . . . . . . . . . . [20 points]
(a) [20 分] 查找演员Annette Nicole作为仆从的演员: 查找电影中演员Annette Nicole作为仆从或没有作为仆从的演员的名字. 答案中不包含Annette Nicole, 且名字按字母排序.
Question 6: 高产出 . . . . . . . . . . . . . . . . . . . . . . . . [5 points]
(a) [5 分] 查找产出影片数量最高的2个年份(根据年份中产出的影片数量). 结果按照时间顺序打印, 且只打印出年份.
Question 7: 相似演员表的电影 . . . . . . . . . . . . . . . . [15 points]
(a) [8 分] 打印电影中演员不同派对关系的影片的数量, 电影中至少有1个演员相同(忽略他们在演员表中的位置).
(b) [7 分] 打印电影中演员不同派对关系的影片的数量, 电影中至少有2个演员相同(忽略他们在演员表中的位置).
Question 8: 轮廓查询 . . . . . . . . . . . . . . . . . . . . . . . . . . . [25 points]
(a) [25 分] 我们想找出一个关于电影影片的集合, 这个集合都具有高人气(即, 高num_ratings)以及高质量(rating)。如果没有一个这样的电影存在 - 在这种情况下, 我们进行所谓的轮廓查询。更具体地说, 我们希望所有的电影都不是由任何其他电影“主导”:
主导的定义 : 电影 “A” 主导 电影 “B”, 如果电影 “A” 胜于 “B”, 即A在这两个标准(高 num_ratings 和 高 rating)都胜于B, 或者只要有其中一个标准中胜过B. 我们则称电影 “A” 主导 电影 “B”.
图 1 给出了一个形象的例子: 实点 (’A’, ’D’, ’F’)并不由任何其他点所主导,从而形成了一个轮廓线。所有其他点都至少被一个其他点所主导: 例如,点 “B” 被点 “A” 所主导, 如图阴影矩形框的右上角有一个点 “A” 。
图 1: 关于轮廓和主导概念的插图 : ’A’ 主导了所有在阴影框中点; ’A’, ’D’ 和 ’F’ 形成了这些点集合的轮廓.
鉴于以上的描述, 请根据评分, 评分的数量打印所有在轮廓上的电影.
¶解答
本文给出了所有在Postgres中测试过的答案, 相信大家可以很容易地在Mysql 或 Sqlite中进行转化.
¶初始化:
1 | ## drop the table if exists |
¶导入数据
这里提供了供进行测试的数据源, 请从我的360云盘地址中下载:
https://yunpan.cn/cSfLzxQApRXSi 访问密码: f3ab
1 | ## 在Postgres中, 请使用copy命令导入数据 |
下图为我在ubuntu系统下的测试结果:
¶解答 1
1 | (a) SELECT name FROM play_in p, movies m |
¶解答 2
1 | SELECT title from movies m, play_in p |
¶解答 3
1 | (a) DROP VIEW IF EXISTS WeigthedRatings; |
¶解答 4
1 | DROP VIEW IF EXISTS RatingGap; |
¶解答 5
1 | DROP VIEW IF EXISTS MastersMovies CASCADE; |
¶解答 6
1 | DROP VIEW IF EXISTS MoviesPerYear; |
¶解答 7
1 | (a) SELECT COUNT(*) FROM |
¶解答 8
1 | DROP VIEW IF EXISTS Dominated; |
¶参考资料
[1] http://www.ruanyifeng.com/blog/2013/12/getting_started_with_postgresql.html
[2] http://www.postgresql.org/docs/
[3] http://www.cs.cmu.edu/~epapalex/15415S14/PostgreSQLReadme.htm
[4] http://www.cs.cmu.edu/~christos/courses/
[5] http://blog.chinaunix.net/uid-20685819-id-4267454.html