topic
There are 2 tables, user table, score table
- 1. Find out the top three subjects in each person's grades
- 2. Find out the top three results of each subject
-- 用户表
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, '[email protected]');
INSERT INTO `user_info`(`id`, `name`, `age`, `email`) VALUES (2, 'jim', 25, '[email protected]');
INSERT INTO `user_info`(`id`, `name`, `age`, `email`) VALUES (3, 'tom', 18, '[email protected]');
-- 成绩表
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);
User Data
Grade Data
1. Find out the top three subjects in each person's grades
problem solving ideas
- Step 1: The grade table is ranked according to the subject scores of each person to obtain the subject score ranking of each person
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
ranking result
- The second step: name the result set obtained in the first step c3, and then query the num less than or equal to 3 in c3 and sort them by subject
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
result
- Step 3: Perform a left join on the final query result and the user_info table to find out the user name
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
result
2. Find out the top three results of each subject
The idea is the same as above, first rank according to the results of each subject, and then filter out the top 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
result