描述
现有试卷作答记录表exam_record(uid:用户ID, exam_id:试卷ID, start_time:开始作答时间, submit_time:交卷时间,没提交的话为NULL, score:得分),示例数据如下:
id | uid | exam_id | start_time | submit_time | score |
---|---|---|---|---|---|
1 | 1001 | 9001 |
| 2021-07-02 09:01:01
| (NULL)
| (NULL) | | 2 | 1002
| 9003
| 2021-09-01 12:01:01
| 2021-09-01 12:21:01
| 60 | | 3 | 1002
| 9002
| 2021-09-02 12:01:01
| 2021-09-02 12:31:01 | 70
| | 4 | 1002
| 9001
| 2021-09-05 19:01:01
| 2021-09-05 19:40:01
| 81
| | 5 | 1002
| 9002
| 2021-07-06 12:01:01
| (NULL)
| (NULL) | | 6 | 1003
| 9003
| 2021-09-07 10:01:01
| 2021-09-07 10:31:01 | 86 | | 7 | 1003
| 9003
| 2021-09-08 12:01:01
| 2021-09-08 12:11:01
| 40
| | 8 | 1003
| 9001
| 2021-09-08 13:01:01
| (NULL)
| (NULL) | | 9 | 1003
| 9002
| 2021-09-08 14:01:01
| (NULL)
| (NULL)
| | 10 | 1003
| 9003
| 2021-09-08 15:01:01
| (NULL)
| (NULL) | | 11 | 1005
| 9001
| 2021-09-01 12:01:01
| 2021-09-01 12:31:01
| 88 | | 12 | 1005
| 9002
| 2021-09-01 12:01:01
| 2021-09-01 12:31:01
| 88 | | 13 | 1005
| 9002
| 2021-09-02 12:11:01
| 2021-09-02 12:31:01
| 89
|
试卷信息表examination_info(exam_id:试卷ID, tag:试卷类别, difficulty:试卷难度, duration:考试时长, release_time:发布时间),示例数据如下:
id | exam_id | tag | difficulty | **duration |
release_time |
---|---|---|---|---|---|
1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 |
| | 2 | 9002 | C++ | easy
| 60
| 2020-02-01 10:00:00
| | 3 | 9003
| 算法
| medium
| 80
| 2020-08-02 10:00:00
|
请从表中统计出 “当月均完成试卷数”不小于3的用户们爱作答的类别及作答次数,按次数降序输出,示例输出如下:
tag | tag_cnt |
---|---|
C++ | 4 |
SQL | 2 |
算法 | 1 |
解释:用户1002和1005在2021年09月的完成试卷数目均为3,其他用户均小于3;然后用户1002和1005作答过的试卷tag分布结果按作答次数降序排序依次为C++、SQL、算法。
示例1
drop table if exists examination_info,exam_record;
CREATE TABLE examination_info (
id int PRIMARY KEY AUTO_INCREMENT COMMENT '自增ID',
exam_id int UNIQUE NOT NULL COMMENT '试卷ID',
tag varchar(32) COMMENT '类别标签',
difficulty varchar(8) COMMENT '难度',
duration int NOT NULL COMMENT '时长',
release_time datetime COMMENT '发布时间'
)CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE TABLE exam_record (
id int PRIMARY KEY AUTO_INCREMENT COMMENT '自增ID',
uid int NOT NULL COMMENT '用户ID',
exam_id int NOT NULL COMMENT '试卷ID',
start_time datetime NOT NULL COMMENT '开始时间',
submit_time datetime COMMENT '提交时间',
score tinyint COMMENT '得分'
)CHARACTER SET utf8 COLLATE utf8_general_ci;
INSERT INTO examination_info(exam_id,tag,difficulty,duration,release_time) VALUES
(9001, 'SQL', 'hard', 60, '2020-01-01 10:00:00'),
(9002, 'C++', 'easy', 60, '2020-02-01 10:00:00'),
(9003, '算法', 'medium', 80, '2020-08-02 10:00:00');
INSERT INTO exam_record(uid,exam_id,start_time,submit_time,score) VALUES
(1001, 9001, '2021-07-02 09:01:01', null, null),
(1002, 9003, '2021-09-01 12:01:01', '2021-09-01 12:21:01', 60),
(1002, 9002, '2021-09-02 12:01:01', '2021-09-02 12:31:01', 70),
(1002, 9001, '2021-09-05 19:01:01', '2021-09-05 19:40:01', 81),
(1002, 9002, '2021-07-06 12:01:01', null, null),
(1003, 9003, '2021-09-07 10:01:01', '2021-09-07 10:31:01', 86),
(1003, 9003, '2021-09-08 12:01:01', '2021-09-08 12:11:01', 40),
(1003, 9001, '2021-09-08 13:01:01', null, null),
(1003, 9002, '2021-09-08 14:01:01', null, null),
(1003, 9003, '2021-09-08 15:01:01', null, null),
(1005, 9001, '2021-09-01 12:01:01', '2021-09-01 12:31:01', 88),
(1005, 9002, '2021-09-01 12:01:01', '2021-09-01 12:31:01', 88),
(1005, 9002, '2021-09-02 12:11:01', '2021-09-02 12:31:01', 89);
输出:
C++|4
SQL|2
算法|1
解答
明确题意:
统计月均完成试卷数不小于3的用户爱作答的类别及作答次数,按次数降序输出
注意:月均完成试卷数不小于3,是 总完成次数/哪些月份提交了数据
如共完成了12次,这10次的记录是在3,5,7这三个月里的;那月平均完成次数就是:12/3=4;
问题拆解:
筛选完成了的试卷的记录。知识点:where
- 筛选月均完成数不小于3的用户。知识点:
- 按用户分组group by uid;
- 统计当前用户完成试卷总数count(exam_id);
- 统计该用户有完成试卷的月份数count(distinct DATE_FORMAT(start_time, “%Y%m”));
- 分组后过滤having count(exam_id) / count(distinct DATE_FORMAT(start_time, “%Y%m”)) >= 3;
- 关联试卷作答记录表和试卷信息表。知识点:join examination_info using(exam_id)
- 筛选满足条件的用户。知识点:where uid in (…)
- 统计这些用户作答的类别及计数。知识点:按用户分组group by uid;计数count(tag);
- 按次数降序输出。知识点:order by tag_cnt desc
标准答案:
select tag, count(tag) as tag_cnt
from exam_record
join examination_info using(exam_id)
where uid in (
select uid
from exam_record
where submit_time is not null
group by uid
having count(exam_id) / count(distinct DATE_FORMAT(start_time, "%Y%m")) >= 3
)
group by tag
order by tag_cnt desc
自己提交的答案:
select examination_info.tag,count(exam_record.exam_id) as tag_cnt
from exam_record
left join examination_info
on exam_record.exam_id=examination_info.exam_id
where uid in(
select uid
from exam_record
where submit_time is not null
group by uid
# having count(exam_record.exam_id)>=3
HAVING COUNT(*) / COUNT(DISTINCT DATE_FORMAT(submit_time, "%Y%m")) >= 3
)
group by exam_record.exam_id
order by count(exam_record.exam_id) desc