经历了腾讯的一面,竟然遇到了和字节一样的sql题,然而写的还是有些问题,面试官指出需要用partition by,于是 开始学习开窗函数吧【必备知识,居然才学习 害
感觉牛客网上的sql题还是不太业务 so买了leetcode的会员开始刷sql。。
and 希望鹅厂赶紧发日常实习offer吧 别吊着了 hr赶紧上班吧。。
https://segmentfault.com/a/1190000016894456 先学习一个教程
https://www.lanhusoft.com/Article/170.html 再来一个
编写一个 SQL 查询,满足条件:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息:
FirstName, LastName, City, State
题解1
数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。 在使用left jion时,on和where条件的区别如下:
1、on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。
2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。
题解2
【觉得不错请点赞】
本题主要考察多表连接。
按题意要求,使用outer join时可以保证指定表的每条记录都出现----即使没有匹配, outer join又可以分为left join, right join, full join。
我们想让Address表中即使没有Person,也让Person有Address属性,所以Address为必须出现表,那么我们可以用 Person表 left join Address,或者反过来用right join。
select A.FirstName, A.LastName, B.City, B.State from Person A left join Address B
on A.PersonId = B.PersonId;
我看了一下运行效率比较高的朋友的解法,在join前先对Address表处理,去除Address里的重复项,然后让Person left join Address。
select A.FirstName, A.LastName, B.City, B.State from Person A left join (
select distinct PersonId, City, State from Address) B
on A.PersonId = B.PersonId;
这样做的好处是,在数据量特别大而且重复量也特别大时,可以节省join次数,从而节省效率,当然当数据量不那么大,重复数据不那么多时,反而会影响效率
题解3
https://leetcode-cn.com/problems/combine-two-tables/solution/tu-jie-sqlmian-shi-ti-duo-biao-ru-he-cha-xun-by-ho/
【题目】
现在有两个表,“学生表”记录了学生的基本信息,有“学号”、“姓名”。
“成绩”表记录了学生选修的课程,以及对应课程的成绩。
这两个表通过“学号”进行关联。
现在要查找出所有学生的学号,姓名,课程和成绩。
【解题思路】
1.确定查询结果
题目要求查询所有学生的姓名,学号,课程和成绩信息
select 学号,姓名,课程,成绩
查询结果的列名“学号”、“姓名”,在“学生”表里,列名“课程”、“成绩”在“成绩”表里,所以需要进行多表查询。
2.哪种联结呢?
涉及到多表查询,在之前的课程《从零学会sql:多表查询》里讲过需要用到联结。
多表的联结又分为以下几种类型:
1)左联结(left join),联结结果保留左表的全部数据
2)右联结(right join),联结结果保留右表的全部数据
3)内联结(inner join==join),取两表的公共数据
这个题目里要求“所有学生”,而“所有学生”在“学生”表里。为什么不在“成绩”表里呢?
如果有的学生没有选修课程,那么他就不会出现在“成绩”表里,所以“成绩”表没有包含“所有学生”。
所以要以“学生”表进行左联结,保留左边表(学生表)里的全部数据。
from 学生信息表 as a left join 成绩表 as b
3.两个表联结条件是什么?
两个表都有“学号”,所以联结条件为学号。
on a.学号=b.学号
4.最终sql
select a.学号,a.姓名,b.课程,b.成绩
from 学生 as a
left join 成绩 as b
on a.学号=b.学号;
【本题考点】
考察多表联结,以及如何选择联结的类型。记住课程里讲过的下面这张图,遇到多表联结的时候从这张图选择对于的sql。
【举一反三】
有下面两个表
编写一个 SQL 查询,满足条件:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息:
FirstName, LastName, City, State
【思路】
从表的结构可以看出,表1(Person)是人的姓名信息,表2(Address)是人的地址信息。
1)查询结果是两个表里的列名,所以需要多表查询
2)考虑到有的人可能没有地址信息,要是查询结构要查所有人,需要保留表1(Person)里的全部数据,所以用左联结(left join)
3)两个表联结条件:两个表通过personId产生联结。
【参考答案】
select FirstName, LastName, City, State
from Person left join Address
on Person.PersonId = Address.PersonId;