SQL40 根据指定记录是否存在输出不同情况
题目主要信息:
- 筛选表中的数据,当有0级用户未完成试卷数大于2时输出每个0级用户的试卷未完成数和未完成率(保留3位小数)
- 若不存在这样的用户,则输出所有有作答记录的用户的这两个指标
- 结果按未完成率升序排序
问题拆分:
- 先找到所有用户各自的完成题数和做的总题数:
- 要计算每位用户的完成题数和做题总数,需根据uid分组。知识点:group by
- uid直接获取,每位用户做题总数使用count统计每组总数。
count(*) as total_cnt
- 对于分组的得分,用if判断如果是null记为1,如果不是记为0,再累加每组的判断结果。
sum(if(score is null, 1, 0)) as incomplete_cnt
知识点:sum、if
- 筛选出的结果记为all_user_table
- 再找到满足题目第一串条件的用户:
- 用户信息和作答信息分布在两个表中,因此要uid将两个表连接。知识点:join...on...
- 要统计每个用户未完成试卷的数量,需要对uid分组。知识点:group by
- 筛选条件是用户等级等于0,且每组总共未完成数量大于等于2.
having sum(if(score is null, 1, 0)) >= 2
知识点:where、having、sum、if
- 筛选出的结果记为level_zero_table
- 在用户信息表右边以uid连接上all_user_table,然后再连接上level_zero_table的uid。知识点:left join
- 从连接后的表格中筛选出用户ID、未完成数(需要判断如果未完成数为null取0)、未完成率(根据未完成数和all_user_table中的每人做题总数计算,需要判断如果未完成数为null取0)。知识点:if、round
- 筛选条件是表level_zero_table中的用户ID不为空,且用户等级为0或者表level_zero_table中的用户ID为空但是表all_user_table中的用户ID不为空。
where (level_zero_table.uid is not null and level = 0) or (level_zero_table.uid is null and all_user_table.uid is not null)
- 按照未完成率升序输出。知识点:order by asc
代码:
select u_i.uid,
if(incomplete_cnt is null, 0, incomplete_cnt) as incomplete_cnt,
round(if(incomplete_cnt is null, 0, incomplete_cnt / total_cnt), 3) as incomplete_rate
from user_info u_i left join(
select uid,
sum(if(score is null, 1, 0)) as incomplete_cnt,
count(*) as total_cnt
from exam_record
group by uid
) all_user_table
on u_i.uid = all_user_table.uid
left join(
select e_r.uid as uid
from exam_record e_r join user_info u_i
on e_r.uid = u_i.uid
where level = 0
group by uid
having sum(if(score is null, 1, 0)) >= 2
) level_zero_table
on 1 = 1
where (level_zero_table.uid is not null and level = 0)
or (level_zero_table.uid is null and all_user_table.uid is not null)
order by incomplete_rate asc