图解面试题:如何找到喜欢的电影?
【题目】
某电影平台(类似豆瓣、猫眼电影)用3个表来记录电影信息。“电影表”中是电影编号、电影名称、电影描述信息。
“类别表”是电影分类信息,类别包括:犯罪电影、爱情电影、科幻电影。
“电影类别表”是对应电影(电影表中的电影编号)属于哪一类(类别表中的电影类别编号)
查找“电影表”中电影描述信息包含“机器人”的电影,以及对应的电影类别名称和电影数目(count(电影表.电影编号))。
同时,还需要该电影类别名称对应电影数量(count(电影类别表.电影类别编号))>=5部。
【解题思路】
我们首先观察输出格式要求:
"机器人"是电影描述信息里面包含的内容,在“电影表”中。电影类别名称在“类别表”中,因此需要将两个表联结。
而观察三个表的列名,我们发现“电影表”和“类别表”没有相同的列名,因此无法直接进行联结,需要借助“电影类别表”进行3表联结。
使用哪种联结呢?拿出《猴子 从零学会SQL》里面的多表联结图。
因为取的是这些表的共同数据,所以使用内联结。三表联结队员的sql如下:
select *from 电影表 as f inner join 电影类别表 as fcon f.电影编号 = fc.电影编号inner join 类别表 as con fc.电影类别编号 = c.电影类别编号;
1.查找电影描述信息中包含"机器人"的电影类别名称
描述信息中包含"机器人",需要用到字符串模糊查询(like)。拿出《猴子 从零学会SQL》里面讲过的字符串模糊查询知识点。
此题是描述信息中包含"机器人",所以应该是 like '%机器人%'。使用where和like进行模糊查询,结果如下:
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)。
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的电影类别编号作为临时表(记为右表)。
select 电影类别编号from 电影类别表group by 电影类别编号having count(电影类别编号) >= 5;
(右表)
2.与前面已经内联结的三个表(左表)通过电影类别编号再进行联结。
(左表)
用哪种联结方式呢?
因为要用到电影类别编号数量大于5的电影类别编号,右表为筛选后的结果。因此需要用到右联结,只保留右表的全部数据,即电影类别编号为3的数据。
3.查找电影描述信息中包含"机器人"的电影
在上一步sql中加入where子句,进行模糊查询
4.根据输出格式要求选择对应的列并用group by对电影类别名称分组
最终sql如下:
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。
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?
- 【Go 语言社区】golang协程——通道channel阻塞
- Oracle 12c PDB中碰到的DG问题 (r10笔记第63天)
- 上线必备 | 高性能ES5.X部署配置清单
- 【Go 语言社区】go 学习中遇到一些语法问题
- Elasticsearch全文检索实战小结——复盘我带的第二个项目
- 当12C PDB遇上JDBC (r10笔记第59天)
- 微信公众平台开发获取用户基本信息--转
- Elasticsearch检索分类深入详解—基础篇
- 通过Java程序测试数据库连接信息 (r10笔记第64天)
- GoldenGate安装简记(r10笔记第78天)
- 【Go 语言社区】各种变量的声明
- 【Go 语言社区】Golang 高效字符串拼接
- 实战 | Elasticsearch实现类Google高级检索
- Golang中time包用法--转
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 工作队列
- O、Θ、Ω、o、ω,别再傻傻分不清了!
- SpringBoot一1(初次使用)+HelloWord
- 到底什么才是真正的空间复杂度?
- RabbitMQ都写了,RocketMQ怎么能落下?
- dotnet ConcurrentDictionary 的 GetOrAdd 性能比 TryGetValue 加 TryAdd 低
- CentOS7下升级GLIBC2.31
- 网络扫描利器Fing之Linux版本使用教程
- dotnet 通过依赖注入的 Scoped 给工作流注入相同的上下文信息
- 微信文章爬虫
- vue 随记(6):构建的艺术
- Centos7发布SpringBoot项目并后台运行
- k8s部署zookeeper集群
- dotnet 使用 SemaphoreSlim 可能的内存泄露
- WPF 绑定继承的样式提示 只能根据带有基类型 IFrameworkInputElement 的目标类型的 Style 样式