SQL61 给出employees表中排名为奇数行的first_name
select first_namefrom (select emp_no, first_name ,row_number() over(order by first_name) as num from employees) ewhere e.num % 2 = 1order by emp_no
解题思路:①窗口函数row_number的作用是赋予唯一的连续位次。巧用窗口函数row_number对数据进行行排序,对first_name进行排序,将得到的位次命名为row_num。②用求余函数找出奇数行。
SQL62 出现三次以上相同积分的情况
select number from grade group by number having count(number) >= 3
解题思路:筛选条件为某一字段出现次数,则要对该字段进行统计,故要先对字段进行分组GROUP BY,第二要设置筛选条件COUNT(number)>=3, 因条件包含聚集函数,所以只能使用HAVING,而不能使用WHERE。
SQL63 刷题通过的题目排名
selectid, number, dense_rank() over(order by number desc) as t_rankfrom passing_numberorder by t_rank, id
解题思路:row_number() 是没有重复值的排序(即使两个记录相等也是不重复的),可以利用它来实现分页,如1,2,3,4
dense_rank() 是连续排序,两个第二名仍然跟着第三名,如1,2,2,3
rank()是跳跃排序,两个第二名下来就是第四名,如1,2,2,4
selectp1.id, p1.number, count(distinct p2.number) as t_rankfrom passing_number p1,passing_number p2where p1.number <= p2.numbergroup by p1.idorder by t_rank, p1.id
解题思路:先自连接,如 id 为5的记录,通过连接可以得出比自己大的只有本身,因此COUNT的结果为1,加 DISTINCT 是在 number 相同的情况下让排名相同。
SQL64 找到每个人的任务
select p.id, p.name, t.contentfrom person pleft join task t on t.person_id = p.id
解题思路:没有任务的显示为空一般用左连接查询
SQL65 异常的邮件概率
select date, round(sum(case when type = 'completed' then 0 else 1 end) * 1.0 / count(*),3) as pfrom email where send_id not in (select id from user where is_blacklist = 1) and receive_id not in (select id from user where is_blacklist = 1)group by date
解题思路:case when then else end可以理解为java的if-else if -else。是流程控制语句或者条件控 制语句,可以自定义逻辑
保留三位小数使用 round(x, y),x代表数,y代表保留的位数。通过使用case和sum来计算未成功的邮件。