当前位置: 首页 > news >正文

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

描述

现有试卷作答记录表exam_record(uid用户ID, exam_id试卷ID, start_time开始作答时间, submit_time交卷时间, score得分),示例数据如下:

iduidexam_idstart_timesubmit_timescore
1100190012021-07-02 09:01:012021-07-02 09:21:0180
2100290012021-09-05 19:01:012021-09-05 19:40:0181
3100290022021-09-02 12:01:01(NULL)(NULL)
4100290032021-09-01 12:01:01(NULL)(NULL)
5100290012021-07-02 19:01:012021-07-02 19:30:0182
6100290022021-07-05 18:01:012021-07-05 18:59:0290
7100390022021-07-06 12:01:01(NULL)(NULL)
8100390032021-09-07 10:01:012021-09-07 10:31:0186
9100490032021-09-06 12:01:01(NULL)(NULL)
10100290032021-09-01 12:01:012021-09-01 12:31:0181
11100590012021-09-01 12:01:012021-09-01 12:31:0188
12100590022021-09-01 12:01:012021-09-01 12:31:0188
13100690022021-09-02 12:11:012021-09-02 12:31:0189

还有一张试卷信息表examination_info(exam_id试卷ID, tag试卷类别, difficulty试卷难度, duration考试时长, release_time发布时间),示例数据如下:

idexam_idtagdifficultydurationrelease_time
19001SQLhard602020-01-01 10:00:00
29002SQLeasy602020-02-01 10:00:00
39003算法medium802020-08-02 10:00:00

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

uidincomplete_cntcomplete_cntdetail
1002242021-09-01:算法;2021-07-02:SQL;2021-09-02:SQL;2021-09-05:SQL;2021-07-05:SQL

解释:2021年的作答记录中,除了1004,其他用户均满足有效用户定义,但只有1002未完成试卷数大于1,因此只输出1002,detail中是1002作答过的试卷{日期:tag}集合,日期和tag间用:连接,多元素间用;连接。

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 completefrom 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

🔍 分步解析

Step 1:子查询 —— 打标签(完成 / 未完成)

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
字段说明
IF(submit_time IS NULL, 1, NULL)如果未交卷 → 记为 1,否则 NULL
IF(submit_time IS NULL, NULL, 1)如果已交卷 → 记为 1,否则 NULL
LEFT JOIN ... USING(exam_id)关联试卷信息,获取 tag 类别
WHERE YEAR(start_time)=2021只看 2021 年的数据

💡 为什么用 NULL?因为 COUNT() 只统计非空值!


Step 2:外层分组统计

GROUP BY uid

按用户分组,准备聚合。


Step 3:用 COUNT() 区分统计“完成”和“未完成”

COUNT(incomplete) AS incomplete_cnt  -- 只统计 non-NULL 的
COUNT(complete)   AS complete_cnt
函数行为
COUNT(列)只统计该列 非 NULL 的行数
SUM(列)会把所有值加起来(如 1+1+1=3)
COUNT(*)统计所有行

👉 所以你用 COUNT(incomplete) 就等于“未完成的次数”!


Step 4:HAVING 筛选用户

HAVING complete_cnt >= 1 AND incomplete_cnt BETWEEN 2 AND 4

✅ 只保留满足条件的用户。

⚠️ 注意:必须用 HAVING,不能用 WHERE,因为 complete_cnt 是聚合结果。


Step 5:生成明细字符串

GROUP_CONCAT(DISTINCT CONCAT_WS(':', DATE(start_time), tag) SEPARATOR ';'
) AS detail
函数说明
CONCAT_WS(':', A, B)把 A 和 B 用 : 拼接 → A:B
DATE(start_time)只取日期部分,如 2021-09-01
DISTINCT去重,避免重复记录
SEPARATOR ';'多个记录之间用 ; 分隔
GROUP_CONCAT(...)把一组字符串拼成一个长串

👉 输出示例:2021-09-01:SQL:2021-09-02:Python


🧠 核心知识点总结

技巧说明适用场景
✅ IF(条件, 值1, NULL) + COUNT()实现条件计数统计满足某条件的行数
✅ COUNT(列) vs COUNT(*)前者忽略 NULL条件聚合
✅ GROUP_CONCAT + CONCAT_WS生成结构化字符串报表、明细导出
✅ HAVING 筛选聚合结果过滤分组后数据用户行为筛选
✅ LEFT JOIN + USING关联获取维度信息主表+维度表
✅ YEAR(date)提取年份时间范围筛选

🛠️ 常见变体(面试常考)

1. 统计“连续未完成”考试

-- 可用 LAG() 判断连续
LAG(submit_time) OVER (PARTITION BY uid ORDER BY start_time)

2. 找出“从未完成过考试”的用户

HAVING complete_cnt = 0

3. 找出“未完成率 > 50%”的用户

HAVING incomplete_cnt * 1.0 / (incomplete_cnt + complete_cnt) > 0.5
http://www.dtcms.com/a/323384.html

相关文章:

  • 9. 堆和栈有什么区别
  • 01数据结构-图的邻接矩阵和遍历
  • 从零开始理解编译原理:设计一个简单的编程语言
  • svg 图片怎么设置 :hover 时变色
  • 交 换
  • sigaction 中 sa_handler = SIG_IGN 的深度解析与应用实践
  • day14 - html5
  • 2025年TOP5服装类跟单软件推荐榜单
  • 复杂正则语句(表格数据)解析
  • CentOS7运行AppImage
  • 历史数据分析——首旅酒店
  • 电子电气架构 --- 48V车载供电架构
  • ubuntu修改密码
  • 基于dynamic的Druid 与 HikariCP 连接池集成配置区别
  • 论文阅读 2025-8-3 [FaceXformer, RadGPT , Uni-CoT]
  • 数论——约数之和、快速乘
  • 新手入门:Git 初次配置与 Gitee 仓库操作全指南 —— 从环境搭建到代码推送一步到位
  • 【unitrix数间混合计算】2.9 小数部分特征(t_non_zero_bin_frac.rs)
  • Java基础-完成局域网内沟通软件的开发
  • day 16 stm32 IIC
  • day 35_2025-08-09
  • 202506 电子学会青少年等级考试机器人四级器人理论真题
  • Java -- 日期类-第一代-第二代-第三代日期
  • 05.【数据结构-C语言】栈(先进后出,栈的实现:进栈、出栈、获取栈顶元素,栈实现代码,括号匹配问题)
  • 分布式事务Seata TCC模式篇
  • 【代码篇】关于PartiallyPassword插件_实现文章加密
  • 不同类型模型的样本组织形式
  • 机器翻译:FastText算法详解与Python的完整实现
  • Java-线程线程的创建方式
  • 十九、MySQL-DQL-基本查询