题解 | #SQL19 未完成试卷数大于1的有效用户#

未完成试卷数大于1的有效用户

http://www.nowcoder.com/practice/46cb7a33f7204f3ba7f6536d2fc04286

明确题意:

统计2021年每个未完成试卷作答数大于1的有效用户的数据(有效用户指完成试卷作答数至少为1且未完成数小于5),输出用户ID、未完成试卷作答数、完成试卷作答数、作答过的试卷tag集合,按未完成试卷数量由多到少排序


问题分解:

  • 关联作答记录和试卷信息:left join examination_info on using(exam_id);(题中exam_record中的exam_id在examination_info均存在,所以用left join和inner join效果一样)
  • 筛选2021年的记录:where year(start_time)=2021
  • 获取各用户的tag,start_time及未完成标记和已完成标记,如果该作答记录交卷了则已完成标记为1,未完成标记为0,否则相反:if(submit_time is null, 1, null) as incomplete
  • 按用户分组:group by uid
  • 统计未完成试卷作答数和已完成试卷作答数:count(incomplete) as incomplete_cnt
  • 统计作答过的tag集合:
    • 对于每条作答tag,用:连接日期和tag:concat_ws(':', date(start_time), tag)
    • 对于一个人(组内)的多条作答,用;连接去重后的作答记录:group_concat(distinct concat_ws(':', date(start_time), tag) SEPARATOR ';')
  • 筛选未完成试卷作答数大于1的有效用户:having complete_cnt >= 1 and incomplete_cnt BETWEEN 2 and 4
    • 完成试卷作答数至少为1:complete_cnt >= 1
    • 未完成数小于5:incomplete_cnt < 5
    • 未完成试卷作答数大于1:incomplete_cnt > 1

细节问题:

  • 表头重命名:as
  • 按未完成试卷数量由多到少排序:order by incomplete_cnt DESC

完整代码:

SELECT uid, count(incomplete) as incomplete_cnt,
    count(complete) as complete_cnt,
    group_concat(distinct concat_ws(':', date(start_time), tag) SEPARATOR ';') as detail
from (
    SELECT uid, tag, start_time,
        if(submit_time is null, 1, null) as incomplete,
        if(submit_time is null, null, 1) as complete
    from exam_record 
    left join examination_info using(exam_id)
    where year(start_time)=2021
) as exam_complete_rec
group by uid
having complete_cnt >= 1 and incomplete_cnt BETWEEN 2 and 4
order by incomplete_cnt DESC
SQL进阶 文章被收录于专栏

SQL进阶step by step

全部评论
老哥真牛,一路看你的题解过来的,现在看问题也是先分解再做,这方法真不错
4 回复 分享
发布于 2022-09-08 11:58 江苏
老哥们,你们自己做题大概一道中等或者较难的题目要花多久阿?我新手第一次刷题,自己做加查查忘记了的函数用法,最快也要快20分钟才做对一题啊。
3 回复 分享
发布于 2021-11-23 22:44
好难,裂开,从进阶挑战开始的题目感觉难度骤升
2 回复 分享
发布于 2022-06-28 19:20
有个疑问,为什么拼接的detail部分用的是start_time,题目说的不是作答过的题目的tag连接吗?但实际上改为submit_time时,测试结果会包含submit_time为空的tag,请大神指引下,谢谢
2 回复 分享
发布于 2022-03-03 15:24
为什么代码一旦格式化后就编译通不过
1 回复 分享
发布于 2023-05-05 17:14 浙江
请问我的理解是对的吗?incomplete和complete是一个字段名(列名),一个字段下可以有多个具体列值,所以例如:if(submit_time is null,1,null) as incomplete会给出一列值(列名为incomplete),如果submit_time为空,记录下为1,即该列(该字段)下新增一条记录为1。
1 回复 分享
发布于 2023-02-17 10:00 辽宁
请问一下为什么select sum(if(submit_time is null, 1, null)) as incomplete_cnt , sum(if(submit_time is null, null, 1)) as complete_cnt,用score,是错误的呢?
1 回复 分享
发布于 2022-01-13 17:31
请问where year(start_time)=2021这里为什么一定要用start_time不能用submit_time呢 用submit_time报错
1 回复 分享
发布于 2021-12-24 11:34
博主你好,运行你的代码后发现一个问题: 答案示例:2021-09-01:算法;2021-07-02:SQL;2021-09-02:SQL;2021-09-05:SQL;2021-07-05:SQL 代码结果:2021-07-02:SQL;2021-07-05:SQL;2021-09-01:算法;2021-09-02:SQL;2021-09-05:SQL 为什么会出现日期升序排列的情况?
点赞 回复 分享
发布于 2024-06-16 12:35 四川
不对啊,这道题只是恰巧两个相同试卷的作答时间都是9月1日,如果不是同一天,group_concat里的distinct就错了,没有对exam_id去重
点赞 回复 分享
发布于 2024-02-27 11:00 浙江
请问楼主,# select执行顺序不是在group by,having之后吗,having里面的incomplete_cnt是怎么筛选出来的(在没有select之前)
点赞 回复 分享
发布于 2023-07-27 08:25 辽宁
select uid,ef.incomplete_cnt,ef.complete_cn,group_concat(distinct concat_ws(":",start_time,tag,separator ";")) as detail from ( select uid,tag,start_time, count(if(score is not null,1,null)) as complete_cnt, count(if(score is null,null,1)) as incomplete_cnt from exam_record er inner join examination_info ei on ei.exam_id=er.exam_id where year(start_time)="2021" ) as ef group by uid having complete_cnt >=1 and incomplete_cnt between 2 and 4 order by incomplete_cnt desc; 请问不能在子查询里就命好名字吗?我这样写,结果显示是错误的
点赞 回复 分享
发布于 2023-02-19 21:08 江苏
这道题怎么感觉逻辑上不需要用left join呢?因为如果出现一个没有详情信息的考试代码,对于detail也没有意义。
点赞 回复 分享
发布于 2022-11-09 12:27 香港
请问一下,为什么 if(submit_time is null, 1, null) as incomplete不能写成 if(submit_time is null, 1, 0) as incomplete,
点赞 回复 分享
发布于 2022-08-16 15:02
select uid, count(start_time)-count(submit_time) as 'incomplete_cnt', Count(submit_time)as'complete_cnt', group_concat(distinct concat_ws(':',date(start_time),tag) separator ';') as'detail' from (select uid, tag, start_time,submit_time from exam_record left join examination_info using(exam_id) where year(submit_time)='2021') as c group by uid having complete_cnt >=1 and incomplete_cnt between 2 AND 4 order by incomplete_cnt Desc 请问为什么我这个incomplete_cnt会出来0的情况呢?
点赞 回复 分享
发布于 2022-05-19 11:31
请问为什么最后一个字段连接时要加distinct呢
点赞 回复 分享
发布于 2022-05-16 20:55
您好,我与您的思路大致相同,但是报错:“Unknown column 'incomplete_cnt' in 'field list'”,可以帮我看看问题出在哪里了吗: select uid,sum(if(submit_time is null,1,0)) as incomplete_cnt, sum(if(submit_time is not null,1,0)) as complete_cnt, group_concat(distinct concat(date_format(start_time,'%Y-%m-%d'),':',tag) order by incomplete_cnt desc separator ';') as detail from exam_record as er join examination_info as ei on er.exam_id=ei.exam_id where year(start_time)=2021 group by uid having complete_cnt>=1 and incomplete_cnt between 2 and 4
点赞 回复 分享
发布于 2022-04-18 11:57
complete_cnt >= 1 and incomplete_cnt BETWEEN 2 and 4 这个地方是个坑,按照题意我也是这么过滤的,结果运行报错。细想才发现incomplete_cnt BETWEEN 2 and 4,已经隐含complete必须>1,having incomplete_cnt BETWEEN 2 and 4 即可
点赞 回复 分享
发布于 2022-03-31 17:16
请问未完成可以这样写吗:count(start_time)-count(submit_time) as imcoplete_cnt
点赞 回复 分享
发布于 2022-02-21 12:48
请问为什么把if(submit_time is null, 1, null) as incomplete 换成统计score会出错
点赞 回复 分享
发布于 2022-02-10 21:45

相关推荐

点赞 评论 收藏
分享
评论
171
46
分享

创作者周榜

更多
牛客网
牛客企业服务