SQL134. 满足条件的用户的试卷完成数和题目练习数
描述
id | uid | nick_name | achievement | level | job | register_time |
1 | 1001 | 牛客1号 | 3100 | 7 | 算法 | 2020-01-01 10:00:00 |
2 | 1002 | 牛客2号 | 2300 | 7 | 算法 | 2020-01-01 10:00:00 |
3 | 1003 | 牛客3号 | 2500 | 7 | 算法 | 2020-01-01 10:00:00 |
4 | 1004 | 牛客4号 | 1200 | 5 | 算法 | 2020-01-01 10:00:00 |
5 | 1005 | 牛客5号 | 1600 | 6 | C++ | 2020-01-01 10:00:00 |
6 | 1006 | 牛客6号 | 2000 | 6 | C++ | 2020-01-01 10:00:00 |
id | exam_id | tag | difficulty | duration | release_time |
1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 |
2 | 9002 | C++ | hard | 60 | 2021-09-01 06:00:00 |
3 | 9003 | 算法 | medium | 80 | 2021-09-01 10:00:00 |
id | uid | exam_id | start_time | submit_time | score |
1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:31:00 | 81 |
2 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 81 |
3 | 1003 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 86 |
4 | 1003 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:51 | 89 |
5 | 1004 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:30:01 | 85 |
6 | 1005 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:02 | 85 |
7 | 1006 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:21:01 | 84 |
8 | 1006 | 9001 | 2021-09-07 10:01:01 | 2021-09-07 10:21:01 | 80 |
id | uid | question_id | submit_time | score |
1 | 1001 | 8001 | 2021-08-02 11:41:01 | 60 |
2 | 1002 | 8001 | 2021-09-02 19:30:01 | 50 |
3 | 1002 | 8001 | 2021-09-02 19:20:01 | 70 |
4 | 1002 | 8002 | 2021-09-02 19:38:01 | 70 |
5 | 1004 | 8001 | 2021-08-02 19:38:01 | 70 |
6 | 1004 | 8002 | 2021-08-02 19:48:01 | 90 |
7 | 1001 | 8002 | 2021-08-02 19:38:01 | 70 |
8 | 1004 | 8002 | 2021-08-02 19:48:01 | 90 |
9 | 1004 | 8002 | 2021-08-02 19:58:01 | 94 |
10 | 1004 | 8003 | 2021-08-02 19:38:01 | 70 |
11 | 1004 | 8003 | 2021-08-02 19:48:01 | 90 |
12 | 1004 | 8003 | 2021-08-01 19:38:01 | 80 |
uid | exam_cnt | question_cnt |
1001 | 1 | 2 |
1003 | 2 | 0 |
示例1
输入:
drop table if exists examination_info,user_info,exam_record,practice_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 user_info ( id int PRIMARY KEY AUTO_INCREMENT COMMENT '自增ID', uid int UNIQUE NOT NULL COMMENT '用户ID', `nick_name` varchar(64) COMMENT '昵称', achievement int COMMENT '成就值', level int COMMENT '用户等级', job varchar(32) COMMENT '职业方向', register_time datetime COMMENT '注册时间' )CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE TABLE practice_record ( id int PRIMARY KEY AUTO_INCREMENT COMMENT '自增ID', uid int NOT NULL COMMENT '用户ID', question_id int NOT NULL COMMENT '题目ID', submit_time datetime COMMENT '提交时间', score tinyint 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 user_info(uid,`nick_name`,achievement,level,job,register_time) VALUES (1001, '牛客1号', 3100, 7, '算法', '2020-01-01 10:00:00'), (1002, '牛客2号', 2300, 7, '算法', '2020-01-01 10:00:00'), (1003, '牛客3号', 2500, 7, '算法', '2020-01-01 10:00:00'), (1004, '牛客4号', 1200, 5, '算法', '2020-01-01 10:00:00'), (1005, '牛客5号', 1600, 6, 'C++', '2020-01-01 10:00:00'), (1006, '牛客6号', 2000, 6, 'C++', '2020-01-01 10:00:00'); INSERT INTO examination_info(exam_id,tag,difficulty,duration,release_time) VALUES (9001, 'SQL', 'hard', 60, '2021-09-01 06:00:00'), (9002, 'C++', 'hard', 60, '2021-09-01 06:00:00'), (9003, '算法', 'medium', 80, '2021-09-01 10:00:00'); INSERT INTO practice_record(uid,question_id,submit_time,score) VALUES (1001, 8001, '2021-08-02 11:41:01', 60), (1002, 8001, '2021-09-02 19:30:01', 50), (1002, 8001, '2021-09-02 19:20:01', 70), (1002, 8002, '2021-09-02 19:38:01', 70), (1004, 8001, '2021-08-02 19:38:01', 70), (1004, 8002, '2021-08-02 19:48:01', 90), (1001, 8002, '2021-08-02 19:38:01', 70), (1004, 8002, '2021-08-02 19:48:01', 90), (1004, 8002, '2021-08-02 19:58:01', 94), (1004, 8003, '2021-08-02 19:38:01', 70), (1004, 8003, '2021-08-02 19:48:01', 90), (1004, 8003, '2021-08-01 19:38:01', 80); INSERT INTO exam_record(uid,exam_id,start_time,submit_time,score) VALUES (1001, 9001, '2021-09-01 09:01:01', '2021-09-01 09:31:00', 81), (1002, 9002, '2021-09-01 12:01:01', '2021-09-01 12:31:01', 81), (1003, 9001, '2021-09-01 19:01:01', '2021-09-01 19:40:01', 86), (1003, 9002, '2021-09-01 12:01:01', '2021-09-01 12:31:51', 89), (1004, 9001, '2021-09-01 19:01:01', '2021-09-01 19:30:01', 85), (1005, 9002, '2021-09-01 12:01:01', '2021-09-01 12:31:02', 85), (1006, 9003, '2021-09-07 10:01:01', '2021-09-07 10:21:01', 84), (1006, 9001, '2021-09-07 10:01:01', '2021-09-07 10:21:01', 80);
输出:
1001|1|2 1003|2|0
Mysql 解法, 执行用时: 37ms, 内存消耗: 6380KB, 提交时间: 2022-01-27
select er1.uid as uid, count(distinct er1.exam_id) as exam_cnt, count(distinct pr1.id) as question_cnt from exam_record er1 left join practice_record pr1 on er1.uid = pr1.uid and year(er1.submit_time)=2021 and YEAR(pr1.submit_time)=2021 where er1.uid in ( select er.uid from user_info ui left join exam_record er on ui.uid = er.uid join examination_info ei on er.exam_id = ei.exam_id where ei.tag = 'SQL' and ui.level = 7 and difficulty = 'hard' and year(submit_time)=2021 group by ui.uid having avg(er.score) >80) group by er1.uid order by exam_cnt , question_cnt desc;
Mysql 解法, 执行用时: 37ms, 内存消耗: 6396KB, 提交时间: 2021-12-02
with info as( select DISTINCT uid from examination_info inner join exam_record using(exam_id) inner join user_info using (uid) where difficulty='hard' and tag='SQL' and submit_time is not NULL and level=7 group by uid having avg(score)>80 ) select DISTINCT user_info.uid, count(distinct exam_record.exam_id)as exam_cnt, count(distinct practice_record.submit_time)as question_cnt from user_info left outer join exam_record on(user_info.uid=exam_record.uid and extract(year from exam_record.submit_time)=2021) left outer join practice_record on(user_info.uid=practice_record.uid and extract(year from practice_record.submit_time)=2021) where user_info.uid in (select * from info) group by user_info.uid order by exam_cnt,user_info.uid desc
Mysql 解法, 执行用时: 37ms, 内存消耗: 6400KB, 提交时间: 2022-01-27
SELECT d.uid ,count(distinct case when substr(d.submit_time,1,4)='2021' then d.id else null end ) exam_cnt ,count(distinct case when substr(e.submit_time,1,4)='2021' then e.id else null end ) question_cnt from exam_record d left join practice_record e on d.uid=e.uid where d.uid in ( select a.uid from user_info a join exam_record b on a.uid=b.uid join examination_info c on c.exam_id=b.exam_id where c.tag='sql' and c.difficulty='hard' and a.level>='7'and substr(submit_time,1,4)='2021' group by a.uid having avg(b.score)>='80') and substr(d.submit_time,1,4)='2021' group by d.uid order by exam_cnt,question_cnt desc;
Mysql 解法, 执行用时: 37ms, 内存消耗: 6400KB, 提交时间: 2021-11-30
with target_user as (#先是筛选特定的用户 select b.uid, avg(b.score) from examination_info a left join exam_record b on a.exam_id=b.exam_id inner join user_info c on b.uid=c.uid and c.level=7 where a.tag='SQL' and a.difficulty='hard' group by b.uid having avg(b.score)>=80 ) #接下来连接三个表,因为exam_record和practice_record 的主键是id, #所以计算次数时可以用dsitinct id select c.uid, count(distinct a.id) as exam_cnt, count(distinct b.id) as question_cnt from target_user c left join exam_record a on a.uid =c.uid and year(a.submit_time)=2021 left join practice_record b on b.uid=c.uid and year(b.submit_time)=2021 group by c.uid order by exam_cnt,question_cnt desc
Mysql 解法, 执行用时: 37ms, 内存消耗: 6404KB, 提交时间: 2022-01-22
select t1.uid, -- count(distinct case when year(t2.submit_time) = '2021' then t2.exam_id else null end) as exam_cnt, -- 不对 -- count(distinct case when year(t3.submit_time) = '2021' then t3.question_id else null end) as question_cnt -- 不对 count(distinct case when year(t2.submit_time) = '2021' then t2.id else null end) as exam_cnt, -- 正确 count(distinct case when year(t3.submit_time) = '2021' then t3.id else null end) as question_cnt -- 正确 from ( select A.uid from exam_record AS A INNER JOIN user_info AS B ON A.uid = B.uid INNER JOIN examination_info AS C ON A.exam_id = C.exam_id where B.level = 7 and C.tag = 'SQL' and C.difficulty = 'hard' group by uid having avg(score) > 80 ) t1 -- join -- 不能用join left join exam_record t2 on t1.uid = t2.uid -- join -- 不能用join left join practice_record t3 on t1.uid = t3.uid -- where year(t2.submit_time) = '2021' and year(t3.submit_time) = '2021' -- 不能在这里统一用where卡条件!! group by t1.uid order by exam_cnt asc , question_cnt desc ; -- 结果按试卷完成数升序,按题目练习数降序