sql 50 题 21-25

sql 复制代码
#21、查询不同老师所教不同课程平均分从高到低显示 
select 
	round(avg(a.s_score),2) as avg_score,
    b.c_id,
    c.t_name
from score a
left join course b
on a.c_id = b.c_id
left join teacher c
on b.t_id = c.t_id
group by a.c_id
order by avg_score desc

你又忘了orderby 的使用。


sql 复制代码
#22、查询所有课程的成绩第2名到第3名的学生信息及该课程成绩
with rankedscore as
	(select 
		rank() over(partition by c_id order by s_score desc) rk,
		s_id,
		s_score,
		c_id
	from score)
select
	a.*,
    rdk.rk,
    rdk.s_score,
    rdk.c_id,
    b.c_name
from
	rankedscore rdk
left join 
	student a
on a.s_id = rdk.s_id
left join course b
on b.c_id = rdk.c_id
where rdk.rk between 2 and 3

题目要求其实应该是总成绩在2.3的人,但是我们这里增加一点难度,写成各科的23名,那么这里新加了【with】查询,使用with可增加代码可读性。


sql 复制代码
#23、统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比
select
	c_id,
    round(100*(sum(case when s_score between 85 and 100 then 1 else 0 end)/sum(case when s_score between 0 and 100 then 1 else 0 end)),2) as A,
	round(100*(sum(case when s_score between 70 and 85 then 1 else 0 end)/sum(case when s_score between 0 and 100 then 1 else 0 end)),2) as B,
	round(100*(sum(case when s_score between 60 and 70 then 1 else 0 end)/sum(case when s_score between 0 and 100 then 1 else 0 end)),2) as C,
	round(100*(sum(case when s_score between 0 and 60 then 1 else 0 end)/sum(case when s_score between 0 and 100 then 1 else 0 end)),2) as D,
	sum(case when s_score between 0 and 60 then 1 else 0 end)
from 
	score
group by c_id
    

这个是你写的,错误的地方有几个,一个是除法是/而非\,第二个,区别between和and,前者是闭区间,后者是开区间,当前后者的取值会更加灵活,如果是> = <= 那么就是两侧闭区间,所以一般多使用后者。有一个写法优化的事情,就是分母不用再复制过来修改,直接使用count(1)来做,count(1)也就是直接统计行数。

修改优化后:

sql 复制代码
SELECT 
    b.c_id,
    b.c_name,
-- [100-85]
    SUM(CASE WHEN a.s_score > 85 AND a.s_score <= 100 THEN 1 ELSE 0 END) AS "[100-85]",
    ROUND(100 * (SUM(CASE WHEN a.s_score > 85 AND a.s_score <= 100 THEN 1 ELSE 0 END) / COUNT(*)), 2) AS "[100-85]%",
-- [85-70]
    SUM(CASE WHEN a.s_score > 70 AND a.s_score <= 85 THEN 1 ELSE 0 END) AS "[85-70]",
    ROUND(100 * (SUM(CASE WHEN a.s_score > 70 AND a.s_score <= 85 THEN 1 ELSE 0 END) / COUNT(*)), 2) AS "[85-70]%",
-- [70-60]
    SUM(CASE WHEN a.s_score > 60 AND a.s_score <= 70 THEN 1 ELSE 0 END) AS "[70-60]",
    ROUND(100 * (SUM(CASE WHEN a.s_score > 60 AND a.s_score <= 70 THEN 1 ELSE 0 END) / COUNT(*)), 2) AS "[70-60]%",
-- [0-60]
    SUM(CASE WHEN a.s_score <= 60 THEN 1 ELSE 0 END) AS "[0-60]",
    ROUND(100 * (SUM(CASE WHEN a.s_score <= 60 THEN 1 ELSE 0 END) / COUNT(*)), 2) AS "[0-60]%"
FROM score a
LEFT JOIN course b ON a.c_id = b.c_id
GROUP BY b.c_id, b.c_name;

来自ai,自己做还是有点问题。。。。。。


sql 复制代码
#24、查询学生平均成绩及其名次 
select
	s_id,
    avg(s_score) as avg_score,
    rank() over(order by avg(s_score) desc) rk
from
	score
group by s_id
order by avg_score  desc

注意 你自己写得是order by 但是以为自己写的是 group by 还看了好久都找不出原因。dence_ranke() 是更优的排序方式。


sql 复制代码
-- 25、查询各科成绩前三名的记录
with ranked_score as
	(select
		s_id,
		c_id,
        s_score,
		rank() over (partition by c_id order by s_score desc) as rk
	from
		score)
select
	rdk.s_id,
	rdk.c_id,
    a.s_name,
    rdk.rk ,
    rdk.s_score
from
	ranked_score as rdk
left join
	student a
on 
 a.s_id = rdk.s_id
where rk <= 3

开窗函数太好用了......


相关推荐
一只鹿鹿鹿2 分钟前
信息化项目管理规范(参考Word文件)
java·大数据·运维·开发语言·数据库
这个DBA有点耶4 分钟前
多模融合数据库深度解析:关系、文档、向量、图如何统一?
数据库·自然语言处理·aigc·dba·改行学it
数据仓库_晨曦21 分钟前
【无标题】
大数据·sql·spark
anew___22 分钟前
《数据库原理》精要解读(三)—— SQL:与数据库对话的艺术
数据库·sql·oracle
KaiwuDB22 分钟前
KWDB 3.2.0 版本发布,数据管理查询增强,安装部署体验全面升级
数据库
暴躁小师兄数据学院29 分钟前
【AI大数据工程师特训笔记】第10讲:数据库用户、权限管理、数据库约束
大数据·数据库·笔记·sql·postgresql
凤山老林40 分钟前
DDD(领域驱动设计)在复杂业务系统中的落地指南
java·开发语言·数据库·ddd·领域驱动
凯瑟琳.奥古斯特1 小时前
子查询原理与实战案例解析
开发语言·数据库·职场和发展·数据库开发
KaMeidebaby1 小时前
卡梅德生物技术快报|酵母双杂交 cDNA 文库构建与蛋白互作筛选流程
服务器·前端·数据库·人工智能·算法
暴躁小师兄数据学院1 小时前
【AI大数据工程师特训笔记】第02讲:PostgreSQL数据库生态全景
大数据·数据库·人工智能·postgresql