查询各科分数最高的科目名称,学生学号,姓名,分数,排名

查询各科分数最高的科目名称,学生学号,姓名,分数,排名

1.有三个表student(学生表),sc(成绩表),course(课程表),其定义和数据如下
student:
sidsnamesagessex
01赵雷1990-01-01
02钱电1990-12-21
03孙风1990-12-20
04李云1990-12-06
05周梅1991-12-01
06吴兰1992-01-01
07郑竹1989-01-01
09张三2017-12-20
10李四2017-12-25
11李四2012-06-06
12赵六2013-06-13
13孙七2014-06-01
sc:
sidcidscore
010180
010290
010399
020170
020260
020380
030180
030280
030380
040150
040230
040320
040460
050176
050287
060131
060334
070289
070398
course:
cidcnametid
01语文02
02数学01
03英语03
04生理学04
解题思路:
1.首先给sc表按照cid分区按照分数降序排序,最后加个排名
select cid,sid,score,row_number() over (partition by CId order by score desc) ranks 
from sc

这里不会row_number() over()函数的同学自行百度,搞清楚rank(),dense_rank(),row_number()的区别,以及配上over()函数的用法。

查询结果为:

在这里插入图片描述

2.然后和student表、course表连接起来,如果有多个最高分,按照名字的先后顺序排序。
select sc.cid,c.cname,sc.sid,s.sname,sc.score,row_number() over (partition by sc.CId order by sc.score desc,s.sname) ranks 
from sc,student s,course c
where s.sid = sc.sid and sc.cid=c.cid

查询的结果为:

在这里插入图片描述

3.要选取每科的最高分,那么我们把上面查询的结果看做一个表,查询条件为ranks=1,那么就是选取的每科的最高分,如果说题目是选取每科的前3名,我们只要加条件ranks<=3就可以了,我们来看代码。
select *
from(
	select sc.cid,c.cname,sc.sid,s.sname,sc.score,row_number() over (partition by sc.CId order by sc.score desc,s.sname) ranks 
	from sc,student s,course c
	where s.sid = sc.sid and sc.cid=c.cid
)a
where ranks=1

查询结果:
在这里插入图片描述

结果没问题,我们来看看每科前3的sql和查询结果。

select *
from(
 select sc.cid,c.cname,sc.sid,s.sname,sc.score,row_number() over (partition by sc.CId order by sc.score desc,s.sname) ranks 
 from sc,student s,course c
 where s.sid = sc.sid and sc.cid=c.cid
)a
where ranks<=3

查询结果:

在这里插入图片描述
结果没毛病,如果大家有更好的方法,或者更高效的方法可以一起讨论,欢迎指正。

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是我写的一个简单的学生成绩管理系统,使用了链表来存储学生信息和成绩,使用了结构体来表示学生信息和成绩: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NAME_LEN 20 // 最大姓名长度 #define MAX_ID_LEN 10 // 最大学号长度 #define MAX_SUBJECTS 5 // 最大科目数 // 学生信息结构体 typedef struct student_info { char name[MAX_NAME_LEN + 1]; // 姓名 char id[MAX_ID_LEN + 1]; // 学号 float scores[MAX_SUBJECTS]; // 各科成绩 float avg_score; // 平均分 struct student_info *next; // 链表指针 } StudentInfo; // 创建新的学生信息节点 StudentInfo *create_student_info_node() { StudentInfo *node = (StudentInfo *)malloc(sizeof(StudentInfo)); memset(node, 0, sizeof(StudentInfo)); node->next = NULL; return node; } // 从键盘输入一个学生信息 void input_student_info(StudentInfo *node) { printf("请输入学生姓名:"); scanf("%s", node->name); printf("请输入学生学号:"); scanf("%s", node->id); printf("请输入各科成绩(共 %d 科):\n", MAX_SUBJECTS); for (int i = 0; i < MAX_SUBJECTS; i++) { printf("请输入第 %d 科成绩:", i + 1); scanf("%f", &node->scores[i]); } // 计算平均分 float total_score = 0; for (int i = 0; i < MAX_SUBJECTS; i++) { total_score += node->scores[i]; } node->avg_score = total_score / MAX_SUBJECTS; } // 打印一个学生信息 void print_student_info(StudentInfo *node) { printf("%s\t%s\t", node->name, node->id); for (int i = 0; i < MAX_SUBJECTS; i++) { printf("%.1f\t", node->scores[i]); } printf("%.1f\n", node->avg_score); } // 打印所有学生信息 void print_all_student_info(StudentInfo *head) { printf("姓名\t学号\t"); for (int i = 0; i < MAX_SUBJECTS; i++) { printf("科目%d\t", i + 1); } printf("平均分\n"); StudentInfo *node = head->next; while (node) { print_student_info(node); node = node->next; } } // 按平均分对学生信息进行排序 void sort_student_info_by_avg_score(StudentInfo *head) { StudentInfo *p, *q, *pre; int i, j; for (i = 0, p = head->next; p; i++, p = p->next) { for (j = 0, pre = head, q = pre->next; j < i; j++, pre = pre->next, q = q->next) { if (p->avg_score > q->avg_score) { pre->next = p; head->next = p->next; p->next = q; break; } } } } // 根据排名查询学生信息 void query_student_info_by_rank(StudentInfo *head) { printf("请输入排名:"); int rank; scanf("%d", &rank); if (rank < 1) { printf("无效排名!\n"); return; } StudentInfo *node = head->next; for (int i = 1; node; i++, node = node->next) { if (i == rank) { printf("第 %d 名学生信息:\n", rank); print_student_info(node); return; } } printf("排名超过学生总数!\n"); } int main() { // 创建头节点 StudentInfo *head = create_student_info_node(); // 录入学生信息 printf("请输入学生数量:"); int count; scanf("%d", &count); for (int i = 0; i < count; i++) { StudentInfo *node = create_student_info_node(); printf("请输入第 %d 个学生信息:\n", i + 1); input_student_info(node); // 将新节点插入链表尾部 StudentInfo *tail = head; while (tail->next) { tail = tail->next; } tail->next = node; } // 按平均分排序 sort_student_info_by_avg_score(head); // 打印所有学生信息 printf("所有学生信息(按平均分排序):\n"); print_all_student_info(head); // 根据排名查询学生信息 query_student_info_by_rank(head); // 释放所有节点内存 StudentInfo *node = head->next; while (node) { StudentInfo *next = node->next; free(node); node = next; } free(head); return 0; } ``` 这个程序可以先输入学生数量,然后逐个录入每个学生姓名学号和各科成绩。录入完成后会按照平均分对学生信息进行排序,并输出所有学生信息。然后可以通过输入排名查询某个学生的信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值