【第6天】SQL快速入门-综合练习(SQL 小虚竹)

回城传送–》《32天SQL筑基》

零、前言

今天是学习 SQL 打卡的第 6 天,每天我会提供一篇文章供群成员阅读( 不需要订阅付钱 )。

希望大家先自己思考,如果实在没有想法,再看下面的解题思路,自己再实现一遍。在小虚竹JAVA社区 中对应的 【打卡贴】打卡,今天的任务就算完成了,养成每天学习打卡的好习惯。

​ 虚竹哥会组织大家一起学习同一篇文章,所以有什么问题都可以在群里问,群里的小伙伴可以迅速地帮到你,一个人可以走得很快,一群人可以走得很远,有一起学习交流的战友,是多么幸运的事情。

​ 我的学习策略很简单,题海策略+ 费曼学习法。如果能把这些题都认认真真自己实现一遍,那意味着 SQL 已经筑基成功了。后面的进阶学习,可以继续跟着我,一起走向架构师之路。

今天的学习内容是:综合练习

一、练习题目

题目链接 难度
综合练习:SQL34 统计复旦用户8月练题情况 ★★★★★
综合练习:SQL35 浙大不同难度题目的正确率 ★★★★★
综合练习:SQL39 21年8月份练题总数 ★★☆☆☆

二、SQL思路

综合练习:SQL34 统计复旦用户8月练题情况

在这里插入图片描述
在这里插入图片描述

初始化数据

drop table if exists `user_profile`;
drop table if  exists `question_practice_detail`;
drop table if  exists `question_detail`;
CREATE TABLE `user_profile` (
`id` int NOT NULL,
`device_id` int NOT NULL,
`gender` varchar(14) NOT NULL,
`age` int ,
`university` varchar(32) NOT NULL,
`gpa` float,
`active_days_within_30` int ,
`question_cnt` int ,
`answer_cnt` int 
);
CREATE TABLE `question_practice_detail` (
`id` int NOT NULL,
`device_id` int NOT NULL,
`question_id`int NOT NULL,
`result` varchar(32) NOT NULL,
`date` date NOT NULL
);
CREATE TABLE `question_detail` (
`id` int NOT NULL,
`question_id`int NOT NULL,
`difficult_level` varchar(32) NOT NULL
);

INSERT INTO user_profile VALUES(1,2138,'male',21,'北京大学',3.4,7,2,12);
INSERT INTO user_profile VALUES(2,3214,'male',null,'复旦大学',4.0,15,5,25);
INSERT INTO user_profile VALUES(3,6543,'female',20,'北京大学',3.2,12,3,30);
INSERT INTO user_profile VALUES(4,2315,'female',23,'浙江大学',3.6,5,1,2);
INSERT INTO user_profile VALUES(5,5432,'male',25,'山东大学',3.8,20,15,70);
INSERT INTO user_profile VALUES(6,2131,'male',28,'山东大学',3.3,15,7,13);
INSERT INTO user_profile VALUES(7,4321,'male',28,'复旦大学',3.6,9,6,52);
INSERT INTO question_practice_detail VALUES(1,2138,111,'wrong','2021-05-03');
INSERT INTO question_practice_detail VALUES(2,3214,112,'wrong','2021-05-09');
INSERT INTO question_practice_detail VALUES(3,3214,113,'wrong','2021-06-15');
INSERT INTO question_practice_detail VALUES(4,6543,111,'right','2021-08-13');
INSERT INTO question_practice_detail VALUES(5,2315,115,'right','2021-08-13');
INSERT INTO question_practice_detail VALUES(6,2315,116,'right','2021-08-14');
INSERT INTO question_practice_detail VALUES(7,2315,117,'wrong','2021-08-15');
INSERT INTO question_practice_detail VALUES(8,3214,112,'wrong','2021-05-09');
INSERT INTO question_practice_detail VALUES(9,3214,113,'wrong','2021-08-15');
INSERT INTO question_practice_detail VALUES(10,6543,111,'right','2021-08-13');
INSERT INTO question_practice_detail VALUES(11,2315,115,'right','2021-08-13');
INSERT INTO question_practice_detail VALUES(12,2315,116,'right','2021-08-14');
INSERT INTO question_practice_detail VALUES(13,2315,117,'wrong','2021-08-15');
INSERT INTO question_practice_detail VALUES(14,3214,112,'wrong','2021-08-16');
INSERT INTO question_practice_detail VALUES(15,3214,113,'wrong','2021-08-18');
INSERT INTO question_practice_detail VALUES(16,6543,111,'right','2021-08-13');
INSERT INTO question_detail VALUES(1,111,'hard');
INSERT INTO question_detail VALUES(2,112,'medium');
INSERT INTO question_detail VALUES(3,113,'easy');
INSERT INTO question_detail VALUES(4,115,'easy');
INSERT INTO question_detail VALUES(5,116,'medium');
INSERT INTO question_detail VALUES(6,117,'easy');

解法

要求统计:

  • 复旦大学的每个用户在8月份练习的总题目数和回答正确的题目数情况
  • 在8月份没有练习过的用户,答题数结果返回0
  • 本题注意:age为null 也记为 25岁以下

分析:

  • 先找出学校是复旦大学的用户

select
t1.device_id,
t1.university
FROM
user_profile t1
where
t1.university = ‘复旦大学’

扫描二维码关注公众号,回复: 14515045 查看本文章

在这里插入图片描述

  • 要找8月份每个用户答题的总数量和答题正确的数量
  • 用户表要关联question_practice_detail表,计算出题目数量,通过字段device_id进行关联

select
t1.device_id,
t1.university
FROM
user_profile t1
left join question_practice_detail t2 on t1.device_id = t2.device_id
and MONTH(t2.date) = ‘08’ and year(t2.date)=‘2021’
where
t1.university = ‘复旦大学’

  • 同时要对用户进行分组统计答题的总数量和答题正确的数量,8月份没有练习过的用户,答题数结果返回0.
  • 分组使用关键词:group by ; 使用条件表达式,如没有答过题,返回0

条件表达式语法:
case
when sex = ‘1’ then ‘男’
when sex = ‘2’ then ‘女’
else ‘其他’ end
注:Case函数只返回第一个符合条件的值,剩下的Case部分将会被自动忽略。

select
  t1.device_id,
  t1.university,
	  sum(
    case
      when t2.result is not null then 1
      else 0
    end
  ) as question_cnt,
  sum(
    case
      when t2.result = 'right' then 1
      else 0
    end
  ) as right_question_cnt
FROM
  user_profile t1
	left join question_practice_detail t2 on  t1.device_id = t2.device_id 
	and MONTH(t2.date) = '08' and year(t2.date)='2021'
where
  t1.university = '复旦大学'

	group by
  t1.device_id
	
	

综合练习:SQL35 浙大不同难度题目的正确率

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

初始化数据

drop table if exists `user_profile`;
drop table if  exists `question_practice_detail`;
drop table if  exists `question_detail`;
CREATE TABLE `user_profile` (
`id` int NOT NULL,
`device_id` int NOT NULL,
`gender` varchar(14) NOT NULL,
`age` int ,
`university` varchar(32) NOT NULL,
`gpa` float,
`active_days_within_30` int ,
`question_cnt` int ,
`answer_cnt` int 
);
CREATE TABLE `question_practice_detail` (
`id` int NOT NULL,
`device_id` int NOT NULL,
`question_id`int NOT NULL,
`result` varchar(32) NOT NULL,
`date` date NOT NULL
);
CREATE TABLE `question_detail` (
`id` int NOT NULL,
`question_id`int NOT NULL,
`difficult_level` varchar(32) NOT NULL
);

INSERT INTO user_profile VALUES(1,2138,'male',21,'北京大学',3.4,7,2,12);
INSERT INTO user_profile VALUES(2,3214,'male',null,'复旦大学',4.0,15,5,25);
INSERT INTO user_profile VALUES(3,6543,'female',20,'北京大学',3.2,12,3,30);
INSERT INTO user_profile VALUES(4,2315,'female',23,'浙江大学',3.6,5,1,2);
INSERT INTO user_profile VALUES(5,5432,'male',25,'山东大学',3.8,20,15,70);
INSERT INTO user_profile VALUES(6,2131,'male',28,'山东大学',3.3,15,7,13);
INSERT INTO user_profile VALUES(7,4321,'male',28,'复旦大学',3.6,9,6,52);
INSERT INTO question_practice_detail VALUES(1,2138,111,'wrong','2021-05-03');
INSERT INTO question_practice_detail VALUES(2,3214,112,'wrong','2021-05-09');
INSERT INTO question_practice_detail VALUES(3,3214,113,'wrong','2021-06-15');
INSERT INTO question_practice_detail VALUES(4,6543,111,'right','2021-08-13');
INSERT INTO question_practice_detail VALUES(5,2315,115,'right','2021-08-13');
INSERT INTO question_practice_detail VALUES(6,2315,116,'right','2021-08-14');
INSERT INTO question_practice_detail VALUES(7,2315,117,'wrong','2021-08-15');
INSERT INTO question_practice_detail VALUES(8,3214,112,'wrong','2021-05-09');
INSERT INTO question_practice_detail VALUES(9,3214,113,'wrong','2021-08-15');
INSERT INTO question_practice_detail VALUES(10,6543,111,'right','2021-08-13');
INSERT INTO question_practice_detail VALUES(11,2315,115,'right','2021-08-13');
INSERT INTO question_practice_detail VALUES(12,2315,116,'right','2021-08-14');
INSERT INTO question_practice_detail VALUES(13,2315,117,'wrong','2021-08-15');
INSERT INTO question_practice_detail VALUES(14,3214,112,'wrong','2021-08-16');
INSERT INTO question_practice_detail VALUES(15,3214,113,'wrong','2021-08-18');
INSERT INTO question_practice_detail VALUES(16,6543,111,'right','2021-08-13');
INSERT INTO question_detail VALUES(1,111,'hard');
INSERT INTO question_detail VALUES(2,112,'medium');
INSERT INTO question_detail VALUES(3,113,'easy');
INSERT INTO question_detail VALUES(4,115,'easy');
INSERT INTO question_detail VALUES(5,116,'medium');
INSERT INTO question_detail VALUES(6,117,'easy');

解法

要求统计:

  • 浙江大学的用户在不同难度题目下答题的正确率情况

分析:

  • 先找出浙江大学的用户

SELECT up.device_id
FROM
user_profile up
WHERE
up.university = ‘浙江大学’

在这里插入图片描述

  • 查看浙江大学用户的答题情况

SELECT up.device_id,qpd.result
FROM
user_profile up
inner join question_practice_detail qpd
on up.device_id = qpd.device_id
WHERE
up.university = ‘浙江大学’

在这里插入图片描述

  • 查看浙江大学用户的答题对应的题目难度

SELECT up.device_id,qpd.result,qd.difficult_level
FROM
user_profile up
inner join question_practice_detail qpd
on up.device_id = qpd.device_id
inner join question_detail qd
on qpd.question_id = qd.question_id
WHERE
up.university = ‘浙江大学’

在这里插入图片描述

  • 按不同难度进行分组,统计答题的正确率情况

SELECT qd.difficult_level,
SUM(
CASE
WHEN qpd.result = ‘right’ THEN 1
ELSE 0
END
) / COUNT(qpd.result)
as correct_rate
FROM
user_profile up
inner join question_practice_detail qpd
on up.device_id = qpd.device_id
inner join question_detail qd
on qpd.question_id = qd.question_id
WHERE
up.university = ‘浙江大学’
GROUP BY
qd.difficult_level

在这里插入图片描述

  • 按照准确率升序输出

SELECT qd.difficult_level,
SUM(
CASE
WHEN qpd.result = ‘right’ THEN 1
ELSE 0
END
) / COUNT(qpd.result)
as correct_rate
FROM
user_profile up
inner join question_practice_detail qpd
on up.device_id = qpd.device_id
inner join question_detail qd
on qpd.question_id = qd.question_id
WHERE
up.university = ‘浙江大学’
GROUP BY
qd.difficult_level
order by
correct_rate asc

在这里插入图片描述

  • 准确率的值要保留4位有效小数
			SELECT qd.difficult_level,
	ROUND(
	SUM(
        CASE
          WHEN qpd.result = 'right' THEN 1
          ELSE 0
        END
      ) / COUNT(qpd.result)
			,
			4
			)
     as correct_rate
FROM
  user_profile up
	inner join question_practice_detail qpd
	on  up.device_id = qpd.device_id
	inner join question_detail qd
	on    qpd.question_id = qd.question_id
 WHERE
  up.university = '浙江大学'
	GROUP BY
  qd.difficult_level
	order by
  correct_rate asc

在这里插入图片描述

综合练习:SQL39 21年8月份练题总数

在这里插入图片描述
在这里插入图片描述

初始化数据

drop table if exists `user_profile`;
drop table if  exists `question_practice_detail`;
CREATE TABLE `user_profile` (
`id` int NOT NULL,
`device_id` int NOT NULL,
`gender` varchar(14) NOT NULL,
`age` int ,
`university` varchar(32) NOT NULL,
`gpa` float,
`active_days_within_30` int ,
`question_cnt` int ,
`answer_cnt` int 
);
CREATE TABLE `question_practice_detail` (
`id` int NOT NULL,
`device_id` int NOT NULL,
`question_id`int NOT NULL,
`result` varchar(32) NOT NULL,
`date` date NOT NULL
);

INSERT INTO user_profile VALUES(1,2138,'male',21,'北京大学',3.4,7,2,12);
INSERT INTO user_profile VALUES(2,3214,'male',null,'复旦大学',4.0,15,5,25);
INSERT INTO user_profile VALUES(3,6543,'female',20,'北京大学',3.2,12,3,30);
INSERT INTO user_profile VALUES(4,2315,'female',23,'浙江大学',3.6,5,1,2);
INSERT INTO user_profile VALUES(5,5432,'male',25,'山东大学',3.8,20,15,70);
INSERT INTO user_profile VALUES(6,2131,'male',28,'山东大学',3.3,15,7,13);
INSERT INTO user_profile VALUES(7,4321,'male',28,'复旦大学',3.6,9,6,52);
INSERT INTO question_practice_detail VALUES(1,2138,111,'wrong','2021-05-03');
INSERT INTO question_practice_detail VALUES(2,3214,112,'wrong','2021-05-09');
INSERT INTO question_practice_detail VALUES(3,3214,113,'wrong','2021-06-15');
INSERT INTO question_practice_detail VALUES(4,6543,111,'right','2021-08-13');
INSERT INTO question_practice_detail VALUES(5,2315,115,'right','2021-08-13');
INSERT INTO question_practice_detail VALUES(6,2315,116,'right','2021-08-14');
INSERT INTO question_practice_detail VALUES(7,2315,117,'wrong','2021-08-15');
INSERT INTO question_practice_detail VALUES(8,3214,112,'wrong','2021-05-09');
INSERT INTO question_practice_detail VALUES(9,3214,113,'wrong','2021-08-15');
INSERT INTO question_practice_detail VALUES(10,6543,111,'right','2021-08-13');
INSERT INTO question_practice_detail VALUES(11,2315,115,'right','2021-08-13');
INSERT INTO question_practice_detail VALUES(12,2315,116,'right','2021-08-14');
INSERT INTO question_practice_detail VALUES(13,2315,117,'wrong','2021-08-15');
INSERT INTO question_practice_detail VALUES(14,3214,112,'wrong','2021-08-16');
INSERT INTO question_practice_detail VALUES(15,3214,113,'wrong','2021-08-18');
INSERT INTO question_practice_detail VALUES(16,6543,111,'right','2021-08-13');

解法

要求统计:

  • 2021年8月份所有练习过题目的总用户数和练习过题目的总次数

分析:

  • 2021年8月份所有练习过题目的总用户数和练习过题目的总次数
  • 只要对question_practice_detail表中的device_id进行去掉,然后计数,就可得练习过题目的总用户数

select count(distinct device_id) as did_cnt
from question_practice_detail
where date like ‘2021-08%’

在这里插入图片描述

  • 对question_practice_detail表中question_id进行计数,就可得练习过题目的总次数
select  count(distinct device_id) as did_cnt,COUNT(question_id) as question_cnt
from question_practice_detail
where date like '2021-08%'

在这里插入图片描述

解法2

  • mysql 的时间格式的字段支持使用字符串型的时间进行比较,date只要大于等于’2021-8-1’,小于等于’2021-8-31’即可
 select count(distinct device_id) as did_cnt,COUNT(question_id) as question_cnt
 from question_practice_detail
 where  date >= '2021-8-1' and date <= '2021-8-31';

解法3

  • 在where条件里使用year函数获取指定日期的年份,使用month函数获取指定日期的月份,也可实现题目的要求
select count(distinct device_id) as did_cnt,COUNT(question_id) as question_cnt
from question_practice_detail
where year(date)=2021
and month(date) = 8

我是虚竹哥,我们明天见~

猜你喜欢

转载自blog.csdn.net/shi_hong_fei_hei/article/details/126372905