题解 | #根据指定记录是否存在输出不同情况#
根据指定记录是否存在输出不同情况
http://www.nowcoder.com/practice/f72d3fc27dc14f3aae76ee9823ccca6b
拿到题目写了select后面的未完成数和未完成率等,但到‘任意一个0级用户未完成试卷数大于2’这个条件一直不会处理,就参考了webary大佬的题解。发现可以用exists来处理存在性条件,顿时茅塞顿开,因为以前学sql的时候了解过,但使用率太低了导致真需要的时候想不起来。
综合下来本题的关键点有以下几点:
1.因为有些用户没有答题,所以查询所有用户的答题情况的时候,要以user_info为主表! 2.要想到 用exists筛选存在性条件 !! 3.合并两种情况,条件互斥,so只可能有一个结果集:UNION ALL !!!
编写代码分两步:
#1.查询 每个用户 的等级 未完成试卷数 和 未完成率 和 总作答数
#因为有些用户没有答题,所以要查询所有用户的答题情况,要以user_info为主表
select ui.uid uid, level, **###一定要是ui.uid 才能和level一一对应,er.uid不行**
count(start_time)-count(submit_time) incomplete_cnt,
round(ifnull((count(start_time)-count(submit_time))/count(start_time),0),3) incomplete_rate,
COUNT(start_time) as total_cnt **#为了方便判断第二种情况,我们多构建一个总作答数 **
from exam_record er
right join user_info ui on er.uid=ui.uid
group by uid
最终代码:
/*
用exists筛选存在性条件
合并上述结果,条件互斥,so只可能有一个结果集:UNION ALL
*/
SELECT uid, incomplete_cnt, incomplete_rate
FROM (
select ui.uid uid, level, ###一定要是ui.uid 才能和level一一对应
count(start_time)-count(submit_time) incomplete_cnt,
round(ifnull((count(start_time)-count(submit_time))/count(start_time),0),3) incomplete_rate,
COUNT(start_time) as total_cnt
from exam_record er
right join user_info ui on er.uid=ui.uid
group by uid
) a
WHERE EXISTS ( #判断为 有任意一个0级用户未完成试卷数大于2
SELECT uid
FROM (
select ui.uid uid, level, ###一定要是ui.uid 才能和level一一对应
count(start_time)-count(submit_time) incomplete_cnt,
round(ifnull((count(start_time)-count(submit_time))/count(start_time),0),3) incomplete_rate,
COUNT(start_time) as total_cnt
from exam_record er
right join user_info ui on er.uid=ui.uid
group by uid
) a
WHERE `level` = 0 AND incomplete_cnt > 2 )
AND level = 0 #输出0级用户的未完成数和未完成率
union all ##两种情况用union all 连接
SELECT uid, incomplete_cnt, incomplete_rate
FROM (
select ui.uid uid, level, ###一定要是ui.uid 才能和level一一对应
count(start_time)-count(submit_time) incomplete_cnt,
round(ifnull((count(start_time)-count(submit_time))/count(start_time),0),3) incomplete_rate,
COUNT(start_time) as total_cnt
from exam_record er
right join user_info ui on er.uid=ui.uid
group by uid
) a
WHERE not EXISTS ( #判断为 没有任意一个0级用户未完成试卷数大于2
SELECT uid
FROM (
select ui.uid uid, level, ###一定要是ui.uid 才能和level一一对应
count(start_time)-count(submit_time) incomplete_cnt,
round(ifnull((count(start_time)-count(submit_time))/count(start_time),0),3) incomplete_rate,
COUNT(start_time) as total_cnt
from exam_record er
right join user_info ui on er.uid=ui.uid
group by uid
) a
WHERE `level` = 0 AND incomplete_cnt > 2 )
AND total_cnt >0 #筛选有作答记录的用户 即总作答数大于0即可
order by incomplete_rate asc
也可以用with那个函数创建临时表,不过我没学过那个方法也不习惯用,还是用from后子查询了。
如果还有不用的可以看看webary大佬的解答,真的写的极为清楚,分析逻辑,每个点都有,感谢大佬!