题目一:考试分数(二)
题目要求:
请你写一个sql语句查询用户分数大于其所在工作(job)分数的平均分的所有grade的属性,并且以id的升序排序
表结构:
运行结果示例:
思路:
首先查询出每种岗位及其对应的平均分数:
select job,avg(score) as avg from grade group by job
接着将上一步的查询结果作为临时表,与主表通过job字段进行连接,查询符合成绩大于平均分数的数据,并按题目要求进行排序。
运行代码示例:
select id,job,score
from grade g
left join (
select job,avg(score) as avg from grade group by job
) t
using(job)
where score> avg
order by id
题目二:牛客的课程订单分析(二)
题目要求:
请你写出一个sql语句查询在2025-10-15以后,同一个用户下单2个以及2个以上状态为购买成功的C++课程或Java课程或Python课程的user_id,并且按照user_id升序排序
表结构:
运行结果示例:
思路:
首先找到符合2025-10-15以后,状态为购买成功,且课程为C++课程或Java课程或Python课程的数据:
select * from order_info where status = 'completed' and product_name in ('c++','Python','Java') and date > '2025-10-15'
再在该数据的基础上,按照用户id分组,使用having子句筛选出每组数据数量大于等于2的用户id。
运行代码示例:
select user_id
from (
select *
from order_info
where status = 'completed' and product_name in ('c++','Python','Java')
and date > '2025-10-15'
) t
group by user_id
having count(*) >=2
order by user_id
题目三:牛客的课程订单分析(三)
题目要求:
请你写出一个sql语句查询在2025-10-15以后,同一个用户下单2个以及2个以上状态为购买成功的C++课程或Java课程或Python课程的订单信息,并且按照order_info的id升序排序
表结构:
运行结果示例:
思路:
本题在上一题的基础上,要我们找到完整的数据信息,但是SQL分组查询时,select中查询的字段必须是和分组字段相关的字段。因此我们可以简单粗暴的在上一题代码的基础上,再套一层查询,查询临时表中用户id与我们上一题找到的用户id相同的数据。
运行代码示例:
select * from (
select *
from order_info
where status = 'completed' and product_name in ('c++','Python','Java')
and date > '2025-10-15'
) t
where user_id in (
select user_id
from (
select *
from order_info
where status = 'completed' and product_name in ('c++','Python','Java')
and date > '2025-10-15'
) t
group by user_id
having count(*) >=2
)
order by id
题目四:牛客的课程订单分析(六)
题目要求:
请你写出一个sql语句查询在2025-10-15以后,同一个用户下单2个以及2个以上状态为购买成功的C++课程或Java课程或Python课程的订单id,是否拼团以及客户端名字信息,最后一列如果是非拼团订单,则显示对应客户端名字,如果是拼团订单,则显示NULL,并且按照order_info的id升序排序
表结构:
运行结果示例:
思路:
在上一题的基础上,增加表连接操作即可。
运行代码示例:
select t2.id,t2.is_group_buy,t1.name as client_name
from client t1 right join
(
select *,count(id) over(partition by user_id) as number
from order_info
where datediff(date,"2025-10-15")>0
and status="completed"
and product_name in ("C++","Java","Python")
) t2
on t1.id=t2.client_id
where t2.number >1
order by t2.id
题目五:今天的刷题量(一)
题目要求:
请你写出一个SQL,查找出当天(对,就是你现在写代码的这一天,实现原理就是后台有特殊程序会将'2999-02-22'这个东西变为今天的日期,并且将'2999-02-21'变为昨天的日期)的每个题单的刷题量,先按提交数量降序排序,如果提交数量一样的话,再按subject_id升序排序
表结构:
运行结果示例:
思路:
获取当天日期用curdate()函数。
连接两张表,按照课程名称和id分组(每个id对应名称不重复,可以直接按此分组,更加严谨),统计每组数据的数量作为刷体量。
ps.该题代码没有问题,但是题目日期的更新时间不是0点,因此存在一定的几率没有输出(因为当前系统时间已经变了,但是题目中表的日期仍然是前一天的)。
运行代码示例:
select name,count(name) as cnt
from submission s1 left join subject s2 on s1.subject_id=s2.id
where create_time = curdate()
group by subject_id,name
order by cnt desc,subject_id
题目六:异常的邮件概率
题目要求:
现在让你写一个sql查询,每一个日期里面,正常用户发送给正常用户邮件失败的概率是多少,结果保留到小数点后面3位(3位之后的四舍五入),并且按照日期升序排序
表结构:
运行结果示例:
思路:
首先找到符合要求(收件人和发件人均不是黑名单用户)的数据作为临时表:
select * from email where send_id not in ( select id from user where is_blacklist = 1 ) and receive_id not in ( select id from user where is_blacklist = 1 )
之后我们就可以在临时表中按照日期分组,找到未成功发送的邮件数/总邮件数作为异常邮件概率。
运行代码示例:
select date,round(sum(case when type = 'no_completed' then 1 else 0 end) / count(type) ,3) as p
from (
select * from email
where send_id not in (
select id from user where is_blacklist = 1
) and receive_id not in (
select id from user where is_blacklist = 1
)
) t
group by date
order by date