32、查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩(自己做出)

本文介绍了一种使用SQL查询来筛选平均成绩大于等于85的学生学号、姓名和平均成绩的方法。通过内连接和分组函数,可以高效地从学生和成绩表中筛选出所需数据。
-- 32、查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩(不重要)
SELECT st.s_id,st.s_name,AVG(sc.s_score)'mean' FROM 
student as st
INNER JOIN
score as sc on st.s_id=sc.s_id
GROUP BY s_id HAVING mean>=85 

在这里插入图片描述

已知年级由班级组成、班级由学生组成,在成绩发布之后每个学生会根据自身成绩的情况做出不同的响应,请基于组合(Composite)模式与访问者(Visitor)模式设计该程序。 主程序关键代码: public class Main { public static void main(String[] args) { /* * 输入代码,请保留 * 数组inputs对应控制台输入 * inputs[0]: 0 - 年级、班级、学生等数据在程序内由createObjectStructure方法创建; * 1 - 年级、班级、学生等数据从控制台输入并经过parseInputs方法分析得到; * inputs[1]: {g01:{c01:{s01-Jack-80,s02-Tom-70},c02:{s03-Green-90,s04-Smith-70}},g02:{c03:{s05-Jones-75,s06-Jerry-85}}} * */ Scanner sc = new Scanner(System.in); String[] inputs = new String[2]; for(int i=0;i<inputs.length;i++){ inputs[i]=sc.nextLine(); } sc.close(); visitor = new ...(); //创建访问者 ...[] grades=null; // 根据输入情况来选择采用何种方式创建年级、班级、学生等对象,并将其组合。 if (Integer.parseInt(inputs[0])==0) grades = createObjectStructure(); else grades = parseInputs(inputs[1]); ....accept(visitor); //接受访问者对象,输出结果 ... } /* 创建年级、班级、学生对象并将其组合起来 */ public static Grade[] createObjectStructure() { /* 创建的年级、班级、学生对象如下: 年级:g01,该年级有以下班级: 班级:c101,该班级有以下学生 学生:s01,Jack,70 ----s04,Green,50 --c102 ----s02,Tom,80 ----s05,Smith,60 g02 --c103 ----s03,Jerry,90 ----s06,Jones,70 */ ... } /* 通过分析strInput字符串创建年级、班级、学生对象并将其组合起来 */ public static Grade[] parseInputs(String strInput) { ... } } 输入格式: 第1行:创建对象的方式,0或1,含义参见主程序关键代码注释 第2行:年级、班级、学生数据,格式为 {年级1:{班级1:{学号1-姓名1-成绩1,...},...},...} 参见输入输出样例 输出格式: 年级 --班级(人数) ----学号1,姓名1,成绩1,passed ----学号2,姓名2,成绩2,failed passed表示通过考试,即分数大于等于60分 failed表示未通过考试,即分数小于60分 输入样例: 当第一行输入为0时,第二行可以输入任意内容,对结果无影响 0 123 当第一行输入为1时,第二行应按指定格式输入年级、班级、学生等实体内容 1 {g01:{c01:{s01-Jack-80,s02-Tom-70},c02:{s03-Green-90,s04-Smith-70}},g02:{c03:{s05-Jones-75,s06-Jerry-85}}} 输出样例: 当第一行输入为0时,输出内容确定,必定为以下内容: g01 --c101(2) ----s01,Jack,70,passed ----s04,Green,50,failed --c102(2) ----s02,Tom,80,passed ----s05,Smith,60,passed g02 --c103(2) ----s03,Jerry,90,passed ----s06,Jones,70,passed 当第一行输入为1时,输出内容由第二行输入数据决定 g01 --c01(2) ----s01,Jack,80,passed ----s02,Tom,70,passed --c02(2) ----s03,Green,90,passed ----s04,Smith,70,passed g02 --c03(2) ----s05,Jones,75,passed ----s06,Jerry,85,passed
07-05
<think> 我们有一个需求:查询平均成绩大于等于85的所有学生学号姓名平均成绩。 根据引用[1]、[2]、[4]的示例,我们可以总结出以下步骤: 1. 我们需要从学生表(student)成绩表(score)中获取数据。 2. 通过学生编号(s_id或studentid)将两个表连接起来。 3. 按学生分组(GROUP BY 学生编号)以计算每个学生平均成绩。 4. 使用HAVING子句筛选平均成绩大于等于85的记录。 5. 选择学号姓名平均成绩(使用AVG函数计算)。 注意:引用[4]中使用了别名,并且连接条件写在WHERE子句中,但我们可以使用更明确的JOIN语法。 假设表结构如下(根据引用推测): - 学生表(student):包含学生学号(s_id 或 id)、姓名(s_name 或 studentname)等字段。 - 成绩表(score):包含学号(s_id 或 studentid)、课程成绩(s_score)等字段。 我们可以这样写SQL: ```sql SELECT st.s_id AS 学号, st.s_name AS 姓名, AVG(sc.s_score) AS 平均成绩 FROM student st INNER JOIN score sc ON st.s_id = sc.s_id GROUP BY st.s_id, st.s_name HAVING AVG(sc.s_score) >= 85; ``` 注意: 1. 在GROUP BY子句中,我们除了按学号分组外,还加了姓名。这是因为一个学号对应一个姓名,且我们在SELECT中选择了姓名。在大多数数据库中,如果SELECT中的非聚合列不在GROUP BY中会报错(除非数据库支持功能依赖,如MySQL在特定模式下)。 2. 如果存在学生没有成绩的情况,使用INNER JOIN会排除这些学生。如果想要包括没有成绩的学生平均成绩为NULL),可以使用LEFT JOIN,但这时平均成绩为NULL,不会满足>=85的条件,所以结果相同。但根据需求,只查询平均成绩>=85学生,所以内连接即可。 另一种写法(如引用[4])使用WHERE进行连接,但为了清晰,推荐使用JOIN。 引用[4]的写法: ```sql SELECT student.id, student.stdentname, AVG(student_score.score) AS a FROM student_score, student WHERE student.id = student_score.studentid GROUP BY student_score.studentid HAVING a>=85; ``` 注意:这种写法中,GROUP BY只按student_score.studentid分组,但SELECT中选择了student.stdentname(姓名),这可能在有些数据库(如MySQL严格模式)中不被允许,因为姓名分组列没有函数依赖关系。因此,我们推荐在GROUP BY中同时包含学号姓名。 因此,调整后的SQL为: ```sql SELECT st.s_id AS 学号, st.s_name AS 姓名, AVG(sc.s_score) AS 平均成绩 FROM student st, score sc WHERE st.s_id = sc.s_id GROUP BY st.s_id, st.s_name HAVING AVG(sc.s_score) >= 85; ``` 但为了可读性现代SQL规范,建议使用显式JOIN。 所以,最终推荐使用显式JOIN的写法。 另外,引用[3]中使用了左连接(LEFT JOIN),但我们的需求是平均成绩>=85,没有成绩的学生不会被包含,所以内连接(INNER JOIN)更合适。 总结:使用内连接,按学号姓名分组,然后使用HAVING条件过滤。 注意:如果同一个学生在成绩表中有多条记录(多门课程的成绩),那么AVG函数会计算所有课程的平均值。 如果表名或字段名与上述不同,请根据实际表结构调整(例如,引用[4]中表名为student_score,而我们假设为score)。请根据实际情况修改表名字段名。 因此,最终的SQL语句如下: </think> 要查询平均成绩大于等于 85 的所有学生学号姓名平均成绩,可以使用以下 SQL 语句: ```sql SELECT st.s_id AS 学号, st.s_name AS 姓名, AVG(sc.s_score) AS 平均成绩 FROM student st INNER JOIN score sc ON st.s_id = sc.s_id GROUP BY st.s_id, st.s_name HAVING AVG(sc.s_score) >= 85; ``` ### 关键点解析: 1. **表连接** `INNER JOIN` 连接学生(`student`)成绩表(`score`),通过学号`s_id`关联[^3][^4] 2. **分组计算** `GROUP BY st.s_id, st.s_name` 确保每个学生作为一个独立的分组 `AVG(sc.s_score)` 计算每个学生平均成绩 $$ \text{平均成绩} = \frac{\sum \text{单科成绩}}{\text{科目数}} $$ 3. **结果筛选** `HAVING AVG(sc.s_score) >= 85` 过滤出平均分≥85学生[^1][^2][^4] (注意:不能在WHERE中使用聚合函数) ### 结果示例: | 学号 | 姓名 | 平均成绩 | |------|------|----------| | 001 | 张三 | 89.5 | | 003 | 李四 | 92.0 | | 007 | 王五 | 86.8 | ### 注意事项: 1. 如果学生没有成绩记录,会被`INNER JOIN`自动排除(如需包含可用`LEFT JOIN`) 2. 确保`GROUP BY`包含所有非聚合列(学号姓名) 3. 大表查询建议在`s_id``s_score`列建立索引
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值