快乐SQL做题 - Day6

Hello!!今天是SQL DAY 6啦~

一起来看看今天有什么题目吧~

闯关开始!

关卡1- 统计各专业学生人数

思路:

观察到最后的输出,即使没有学生的department也要被列出,所以我们要把department表作为主表,然后left join student 表。

题目还要求要计算人数,那就在前面count()

最后记得要group by department

和设定排序~

select d.dept_name, count(s.student_id) as student_number from department d

left join student s

on d.dept_id = s.dept_id  

group by d.dept_id  

order by student_number desc,d.dept_name asc

恭喜过关!进入下一关!


关卡2 - 寻找用户推荐人

思路:

题目要求referee_id 不是 2,翻译过来就是 referee_id != 2

但还有问题,为什么呢

因为null不会被计入

所以我们就要多一个or is null 

select name from customer

where referee_id is null 

or referee_id != 2

恭喜过关!进入下一关!


关卡3 - 2016年的投资

思路:

首先,为了判断一个值在某一列中是不是唯一的,我们可以使用 GROUP BY 和 COUNT。

其次,这道题可以分成两部分,第一部分是2015投保额相同,第二部分是经纬度不同。

处理第二部分的时候,由于经度纬度要整合起来看,所以用concat(lat,lon)

需要注意的是,要用round(,2)保留两位小数。

select round(sum(TIV_2016),2) as TIV_2016 from insurance 

where TIV_2015 in (

select TIV_2015 from insurance 

group by TIV_2015

having count(TIV_2015)>1)  #以上为第一部分

and concat(LAT,LON) in (

select concat(LAT,LON) from insurance

group by concat(LAT,LON)

having count(PID)=1

) #以上为第二部分

恭喜过关!进入下一关!


关卡4 - 订单最多的客户

思路:

这道题,再一次提醒愚蠢的我,遇到这种求最大/最小的题目,不要去想max(count()),直接排序然后limit1就可以了!!

select customer_number from orders

group by customer_number

order by count(customer_number) desc

limit 1

恭喜过关!进入下一关!


关卡5 - 好友申请 I:总体通过率

思路:

这道题我们需要一个计算的公式,首先求通过率,求通过率的时候因为申请不是唯一,所以我们可以加一个distinct。

然后因为分母有可能为 0。所以我们需要使用ifnull函数来处理这种特殊情况。

最后是一个round来确定他的小数点在两位。

Select round (ifnull(count(distinct(concat(r.requester_id, r.accepter_id))) / count(distinct(concat(f.sender_id, f.send_to_id)))

,0),2) as accept_rate 

from FriendRequest f,RequestAccepted r

这里from两个表的和left join的区别是,from两个表是普通的联接,结果中的记录在两个表中都有。一个是左外联接,结果中的记录在A表中存在,B表中不一定有。

恭喜过关!


今天学到的新知识:concat()可以把两列加在一起;求最大不要max(count()), order by 然后 limit 1 就是很好的选择。from两个表的和left join的区别是,from两个表是普通的联接,结果中的记录在两个表中都有,一个是左外联接,结果中的记录在A表中存在,B表中不一定有。

明天继续闯关~yay ~

你可能感兴趣的:(快乐SQL做题 - Day6)