前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >图解面试题:如何找到喜欢的电影?

图解面试题:如何找到喜欢的电影?

原创
作者头像
猴子聊数据分析
修改2020-08-11 10:22:52
1.1K0
修改2020-08-11 10:22:52
举报

【题目】

某电影平台(类似豆瓣、猫眼电影)用3个表来记录电影信息。“电影表”中是电影编号、电影名称、电影描述信息。

“类别表”是电影分类信息,类别包括:犯罪电影、爱情电影、科幻电影。

“电影类别表”是对应电影(电影表中的电影编号)属于哪一类(类别表中的电影类别编号)

查找“电影表”中电影描述信息包含“机器人”的电影,以及对应的电影类别名称和电影数目(count(电影表.电影编号))。

同时,还需要该电影类别名称对应电影数量(count(电影类别表.电影类别编号))>=5部。

【解题思路】

我们首先观察输出格式要求:

"机器人"是电影描述信息里面包含的内容,在“电影表”中。电影类别名称在“类别表”中,因此需要将两个表联结。

而观察三个表的列名,我们发现“电影表”和“类别表”没有相同的列名,因此无法直接进行联结,需要借助“电影类别表”进行3表联结。

使用哪种联结呢?拿出《猴子 从零学会SQL》里面的多表联结图。

因为取的是这些表的共同数据,所以使用内联结。三表联结队员的sql如下:

代码语言:javascript
复制
select *from 电影表 as f inner join 电影类别表 as fcon f.电影编号 = fc.电影编号inner join 类别表 as con fc.电影类别编号 = c.电影类别编号;

1.查找电影描述信息中包含"机器人"的电影类别名称

描述信息中包含"机器人",需要用到字符串模糊查询(like)。拿出《猴子 从零学会SQL》里面讲过的字符串模糊查询知识点。

此题是描述信息中包含"机器人",所以应该是 like '%机器人%'。使用where和like进行模糊查询,结果如下:

代码语言:javascript
复制
select *from 电影表 as f inner join 电影类别表 as fcon f.电影编号 = fc.电影编号inner join 类别表 as con fc.电影类别编号 = c.电影类别编号where f.电影描述信息 like '%机器人%';;

2.上述电影类别名称对应的电影数量(电影类别表.电影类别编号)>=5部

按照输出格式要求,我们会想到先分组(按电影类别,group by c.电影类别名称)汇总(电影数量,count(f.电影编号)),再用having子句对分组结果进行筛选(having count(c.电影类别编号) >= 5)。

代码语言:javascript
复制
select c.电影类别名称,count(f.电影编号) as 电影数目from 电影表 as f inner join 电影类别表 as fcon f.电影编号 = fc.电影编号inner join 类别表 as con fc.电影类别编号 = c.电影类别编号where f.电影描述信息 like '%机器人%' group by c.电影类别名称having count(c.电影类别编号) >= 5;

可以看出结果为Null了,是这样吗?

下图红色部分中的科幻类别对应的电影数量为5也满足这些条件,但是为什么按照上述语句得出的结果Null?

因为该题有个陷阱:按照题目顺序,我们容易先用where和like查找出对应的电影,最后再用having count(电影类别编号) >= 5来筛选,最后会发现结果为Null。

但是,《猴子 从零学会SQL》里讲过的SQL运行顺序是这样的:

会先运行where子句,此时结果只有一行了:

所以count(电影类别编号) = 1,再用having count(电影类别编号) >= 5来筛选结果只会是Null。

而题目中的上述分类对应电影数量>=5部,是指该电影类别在原始表中的电影数量>= 5,而不是先用where子句筛选以后的表。

那么,这就需要把having子句放在where子句之前,如何到呢?

也就是,需要先对原始表使用条件(电影类别名称对应的电影数量>=5部)筛选数据,然后再运行条件(电影描述信息包含“机器人”的电影对应的电影类别名称以及电影数目)筛选数据。

这就需要把用having子句筛选出的数据作为临时表。所以,正确的答题步骤修改为以下内容。

1.查询出电影类别编号数量大于5的电影类别编号作为临时表(记为右表)。

代码语言:javascript
复制
select 电影类别编号from 电影类别表group by 电影类别编号having count(电影类别编号) >= 5;

(右表)

2.与前面已经内联结的三个表(左表)通过电影类别编号再进行联结。

(左表)

用哪种联结方式呢?

因为要用到电影类别编号数量大于5的电影类别编号,右表为筛选后的结果。因此需要用到右联结,只保留右表的全部数据,即电影类别编号为3的数据。

3.查找电影描述信息中包含"机器人"的电影

在上一步sql中加入where子句,进行模糊查询

4.根据输出格式要求选择对应的列并用group by对电影类别名称分组

最终sql如下:

代码语言:javascript
复制
select c.电影类别名称,count(f.电影编号) as 电影数目from 电影表 as f inner join 电影类别表 as fcon f.电影编号 = fc.电影编号inner join 类别表 as con fc.电影类别编号 = c.电影类别编号right join (select 电影类别编号from 电影类别表group by 电影类别编号having count(电影类别编号) >= 5) as ccon fc.电影类别编号 = cc.电影类别编号where f.电影描述信息 like '%机器人%'group by c.电影类别名称;

【本题考点】

1.考查多表联结。需要知道什么情况下使用哪种联结。

2.模糊查询like

3.考查sql的运行顺序,记住下面这张图。

【举一反三】

从下面的科目表中查找姓“猴”的学生对应的科目类型以及科目数量。同时,还需要满足该科目类型对应的科目数量大于或等于3。

代码语言:javascript
复制
select a.科目类型,count(a.科目) as 科目数量from 科目表 as aright join (select 科目类型from 科目表group by 科目类型having count(科目类型) >= 3) as bon a.科目类型 = b.科目类型where 姓名 like '猴%'group by a.科目类型;

推荐:如何从零学会sql?

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档