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 ~