题目
有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
结果