MYSQL8查询每个人成绩前三的学科或每个学科前三的成绩

文章提供了一种SQL解决方案,用于从用户表和成绩表中分别找出每个用户成绩最好的前三名学科以及每个学科的前三名成绩。通过子查询计算每个用户的科目排名,然后筛选出排名在前三的结果,最后进行左连接以获取用户姓名。
摘要由CSDN通过智能技术生成

题目

有2张表,用户表,成绩表

  • 1、找出每个人成绩前三学科
  • 2、找出每个学科前三的成绩
-- 用户表
CREATE TABLE `user_info` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `age` int DEFAULT NULL,
  `email` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- 用户数据
INSERT INTO `user_info`(`id`, `name`, `age`, `email`) VALUES (1, 'moss', 33, 'moss@126.com');
INSERT INTO `user_info`(`id`, `name`, `age`, `email`) VALUES (2, 'jim', 25, 'jim@qq.com');
INSERT INTO `user_info`(`id`, `name`, `age`, `email`) VALUES (3, 'tom', 18, 'tom@yahu.cn');

-- 成绩表
CREATE TABLE `user_course` (
  `id` int NOT NULL AUTO_INCREMENT,
  `user_id` int DEFAULT NULL,
  `course` varchar(30) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `score` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- 成绩数据
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (1, 1, '语文', 90);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (2, 1, '数学', 66);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (3, 1, '英语', 80);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (4, 1, '物理', 50);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (5, 1, '综合', 100);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (6, 2, '语文', 88);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (7, 2, '数学', 70);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (8, 2, '英语', 99);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (9, 2, '政治', 70);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (10, 2, '艺术', 66);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (11, 3, '语文', 68);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (12, 3, '画画', 80);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (13, 3, '化学', 70);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (14, 3, '英语', 98);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (15, 4, '语文', 80);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (16, 4, '英语', 88);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (17, 4, '数学', 90);
INSERT INTO `user_course`(`id`, `user_id`, `course`, `score`) VALUES (18, 4, '历史', 99);

用户数据
在这里插入图片描述
成绩数据
在这里插入图片描述

1、找出每个人成绩前三学科
解题思路
  • 第一步: 成绩表按每人学科成绩排名得出每个人的学科成绩排名
SELECT c1.user_id, c1.course, c1.score, (
		SELECT count(DISTINCT c2.score)
		FROM user_course c2 
		WHERE c1.score < c2.score
			AND c1.user_id = c2.user_id
	) + 1 AS num
FROM user_course c1 
ORDER BY c1.user_id, num

排名结果
在这里插入图片描述

  • 第二步: 将第一步所得的结果集命名为c3,然后将c3中num小于等于3的查询出来并按学科排序
SELECT c3.user_id, c3.course, c3.score
FROM (
	SELECT c1.user_id, c1.course, c1.score, (
			SELECT count(DISTINCT c2.score)
			FROM user_course c2 
			WHERE c1.score < c2.score
				AND c1.user_id = c2.user_id
		) + 1 AS num
	FROM user_course c1 
	HAVING num <= 3
	ORDER BY c1.user_id, num
) c3 
ORDER BY c3.user_id ASC, c3.score DESC

结果
在这里插入图片描述

  • 第三步: 对最终查询结果与user_info两表进行左连接查出用户名
select u.name, c4.course, c4.score 
from user_info u 
LEFT JOIN (
	SELECT c3.user_id, c3.course, c3.score
	FROM (
		SELECT c1.user_id, c1.course, c1.score, (
				SELECT count(DISTINCT c2.score)
				FROM user_course c2 
				WHERE c1.score < c2.score
					AND c1.user_id = c2.user_id
			) + 1 AS num
		FROM user_course c1 
		HAVING num <= 3
		ORDER BY c1.user_id, num
	) c3 
	ORDER BY c3.user_id ASC, c3.score DESC
) c4 ON u.id = c4.user_id

结果
在这里插入图片描述

2、找出每个学科前三的成绩

思路与上面的一样,先按每个学科的成绩排名,然后筛选出前3的即可

SELECT c3.user_id, c3.course, c3.score
FROM (
	SELECT c1.user_id, c1.course, c1.score, (
			SELECT count(DISTINCT c2.score)
			FROM user_course c2 
			WHERE c1.score <= c2.score
				AND c1.course = c2.course
		) AS num
	FROM user_course c1 
	HAVING num <= 3 
	ORDER BY c1.course, c1.score desc 
) c3 

结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值