SQL练习——经典50题

1. 经典50题

原博客链接

1.1 简介

表格

  • 学生表(Student)
    在这里插入图片描述

  • 课程表(Course)

    在这里插入图片描述

  • 教师表(Teacher)
    在这里插入图片描述

  • 成绩表(Score)
    在这里插入图片描述

数据插入

# Student 学生表
CREATE TABLE Student
(
s_id VARCHAR(20),
s_name VARCHAR(20) NOT NULL,
s_birth VARCHAR(20) NOT NULL, 
s_sex VARCHAR(10) NOT NULL,
PRIMARY KEY(s_id)
);

INSERT INTO Student VALUES('01', '赵雷', '1990-01-01', '男');
INSERT INTO Student VALUES('02', '钱电', '1990-12-21', '男');
INSERT INTO Student VALUES('03', '孙风', '1990-05-20', '男');
INSERT INTO Student VALUES('04', '李云', '1990-08-06', '男');
INSERT INTO Student VALUES('05', '周梅', '1991-12-01', '女');
INSERT INTO Student VALUES('06', '吴兰', '1992-03-01', '女');
INSERT INTO Student VALUES('07', '郑竹', '1989-07-01', '女');
INSERT INTO Student VALUES('08', '王菊', '1990-01-20', '女');


# Course 课程表
CREATE TABLE Course
(
c_id VARCHAR(20),
c_name VARCHAR(20) NOT NULL,
t_id VARCHAR(20) NOT NULL,
PRIMARY KEY(c_id)
);

INSERT INTO Course VALUES('01', '语文', '02');
INSERT INTO Course VALUES('02', '数学', '01');
INSERT INTO Course VALUES('03', '英语', '03');


# Teacher 教师表
CREATE TABLE Teacher
(
t_id VARCHAR(20),
t_name VARCHAR(20) NOT NULL DEFAULT '',
PRIMARY KEY(t_id)
);

INSERT INTO Teacher VALUES('01', '张三');
INSERT INTO Teacher VALUES('02', '李四');
INSERT INTO Teacher VALUES('03', '王五');


# Score 分数表
CREATE TABLE Score
(
s_id VARCHAR(20),
c_id VARCHAR(20),
s_score INT(3),
PRIMARY KEY(s_id, c_id)  # 注意这里是联合主键
);

INSERT INTO Score VALUES('01', '01', 80);
INSERT INTO Score VALUES('01', '02', 90);
INSERT INTO Score VALUES('01', '03', 99);
INSERT INTO Score VALUES('02', '01', 70);
INSERT INTO Score VALUES('02', '02', 60);
INSERT INTO Score VALUES('02', '03', 80);
INSERT INTO Score VALUES('03', '01', 80);
INSERT INTO Score VALUES('03', '02', 80);
INSERT INTO Score VALUES('03', '03', 80);
INSERT INTO Score VALUES('04', '01', 50);
INSERT INTO Score VALUES('04', '02', 30);
INSERT INTO Score VALUES('04', '03', 20);
INSERT INTO Score VALUES('05', '01', 76);
INSERT INTO Score VALUES('05', '02', 87);
INSERT INTO Score VALUES('06', '01', 31);
INSERT INTO Score VALUES('06', '03', 34);
INSERT INTO Score VALUES('07', '02', 89);
INSERT INTO Score VALUES('07', '03', 98);

1.2 题目概览

1、查询课程编号为“01”的课程比“02”的课程成绩高的所有学生的学号和成绩
2、查询平均成绩大于60分的学生的学号和平均成绩
2.1、所有成绩小于60分的学生信息
2.2、查询平均成绩小于60分的学生的学号和平均成绩,考虑没参加考试的情况
3、查询所有学生的学号、姓名、选课数、总成绩
4、查询姓“猴”的老师的个数
5、查询没学过“张三”老师课的学生的学号、姓名
6、查询学过“张三”老师所教的所有课的同学的学号、姓名
7、查询学过编号为“01”的课程并且也学过编号为“02”的课程的学生的学号、姓名(!)
7.1、查询学过编号为“01”的课程但没有学过编号为“02”的课程的学生的学号、姓名(!)
8、查询课程编号为“02”的总成绩
9、查询所有课程成绩小于60分的学生的学号、姓名
10、查询没有学全所有课的学生的学号、姓名 (!)
11、查询至少有一门课与学号为“01”的学生所学课程相同的学生的学号和姓名
12、查询和“01”号同学所学课程完全相同的其他同学的学号(!)
13、查询没学过"张三"老师讲授的任一门课程的学生姓名(?)
15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
16、检索"01"课程分数小于60,按分数降序排列的学生信息
17、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
18、查询各科成绩最高分、最低分和平均分:以如下形式显示:
19、按各科成绩进行排序,并显示排名
20、查询学生的总成绩并进行排名
21 、查询不同老师所教不同课程平均分从高到低显示
22、查询所有课程的成绩第2名到第3名的学生信息及该课程成绩
23、使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,分别统计各分数段人数:课程ID和课程名称
24、查询学生平均成绩及其名次
25、查询各科成绩前三名的记录(不考虑成绩并列情况)
26、查询每门课程被选修的学生数
27、查询出只有两门课程的全部学生的学号和姓名
28、查询男生、女生人数
29、查询名字中含有"风"字的学生信息
31、查询1990年出生的学生名单
32、查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩
33、查询每门课程的平均成绩,结果按平均成绩升序排序,平均成绩相同时,按课程号降序排列
34、查询课程名称为"数学",且分数低于60的学生姓名和分数
35、查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
36、查询任何一门课程成绩在70分以上的姓名、课程名称和分数
37、查询学生不及格的课程并按课程号从大到小排列
38、查询课程编号为03且课程成绩在80分以上的学生的学号和姓名
39、求每门课程的学生人数
40、查询选修“张三”老师所授课程的学生中成绩最高的学生姓名及其成绩
41.查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
42、查询每门功成绩最好的前两名
43、统计每门课程的学生选修人数(超过5人的课程才统计)
44、检索至少选修两门课程的学生学号
45、查询选修了全部课程的学生信息
46、查询各学生的年龄(精确到月份)
47、查询没学过“张三”老师讲授的任一门课程的学生姓名
48、查询两门以上不及格课程的同学的学号及其平均成绩
49、查询本月过生日的学生
49.1、查询下月过生日的学生
50、查询本周过生日的学生
50.1、查询下周过生日的学生

1.3 解答

1、查询课程编号为“01”的课程比“02”的课程成绩高的所有学生的学号和成绩

SELECT
	student.*,
	m.score1,
	m.score2 
FROM
	student
	INNER JOIN (
SELECT
	s1.s_id,
	s1.s_score score1,
	s2.s_score score2 
FROM
	score s1
	JOIN score s2 ON s1.s_id = s2.s_id 
	AND s1.c_id = 1 
	AND s2.c_id = 2 
	AND s1.s_score > s2.s_score 
	) m ON student.s_id = m.s_id

2、查询平均成绩大于60分的学生的学号和平均成绩

SELECT
	* 
FROM
	( SELECT s.s_id id, AVG( s.s_score ) avg_score FROM score s GROUP BY s.s_id ) m 
WHERE
	m.avg_score > 60
	
-- HAVING 子句
-- 在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与聚合函数一起使用。HAVING 子句可以让我们筛选分组后的各组数据。

SELECT s_id, AVG(s_score) avg_score 
FROM Score
GROUP BY s_id
HAVING avg_score > 60;

2.1、所有成绩小于60分的学生信息

SELECT
	student.* 
FROM
	student
	INNER JOIN ( SELECT s_id, MAX( s_score ) max FROM score GROUP BY s_id HAVING max < 60 ) m ON student.s_id = m.s_id
-- 用in
SELECT
	student.* 
FROM
	student
WHERE
	student.s_id IN
	 ( SELECT s_id FROM score GROUP BY s_id HAVING MAX( s_score ) < 60 ) 

2.2、查询平均成绩小于60分的学生的学号和平均成绩,考虑没参加考试的情况

SELECT
	t.id,
	AVG( t.score ) avgscore 
FROM
	(
SELECT
	st.s_id id,
	IFNULL( sc.s_score, 0 ) score 
FROM
	student st
	LEFT JOIN score sc ON st.s_id = sc.s_id 
	) t 
GROUP BY
	t.id 
HAVING
	avgscore < 60

3、查询所有学生的学号、姓名、选课数、总成绩

SELECT
	st.s_id,
	st.s_name,
	COUNT( sc.c_id ),
	SUM( IFNULL( sc.s_score, 0 ) ) totalscore
FROM
	student st
	LEFT JOIN score sc ON st.s_id = sc.s_id
GROUP BY
	st.s_id

4、查询姓“猴”的老师的个数

SELECT
	COUNT( t_id ) 
FROM
	teacher 
WHERE
	t_name LIKE '猴%'

5、查询没学过“张三”老师课的学生的学号、姓名

SELECT
	st.s_id,
	st.s_name 
FROM
	student st 
WHERE
	st.s_id NOT IN (
SELECT
	s_id 
FROM
	score 
WHERE
	c_id IN ( SELECT c_id FROM course WHERE t_id IN ( SELECT t_id FROM teacher WHERE t_name = '张三' ) ) 
	)

6、查询学过“张三”老师所教的所有课的同学的学号、姓名

SELECT
	s_id,
	s_name 
FROM
	student t 
WHERE
	t.s_id IN (
SELECT
	score.s_id 
FROM
	course
	RIGHT JOIN teacher ON course.t_id = teacher.t_id
	LEFT JOIN score ON course.c_id = score.c_id 
WHERE
	teacher.t_name = '张三' 
	)

7、查询学过编号为“01”的课程并且也学过编号为“02”的课程的学生的学号、姓名

SELECT
	s_id,
	s_name 
FROM
	student 
WHERE
	s_id IN (
SELECT
	s1.s_id 
FROM
	score s1
	JOIN score s2 ON s1.s_id = s2.s_id 
WHERE
	s1.c_id = '01' 
	AND s2.c_id = '02' 
	)

7.1、查询学过编号为“01”的课程但没有学过编号为“02”的课程的学生的学号、姓名

SELECT
	student.s_id,
	student.s_name 
FROM
	student 
WHERE
	student.s_id IN (
SELECT
	sc1.s_id 
FROM
	score sc1 
WHERE
	sc1.c_id = '01' 
	AND sc1.s_id NOT IN ( SELECT sc2.s_id FROM score sc2 WHERE sc2.c_id = '02' ) 
	)

8、查询课程编号为“02”的总成绩

SELECT
	SUM( s_score ) 
FROM
	score 
WHERE
	c_id = '02'
# ------------------------OR---------------------------
SELECT SUM(s_score)
FROM Score
GROUP BY c_id
-- WHERE c_id = '02'  # 考察 HAVING,聚合条件限制不能使用WHERE
HAVING c_id = '02'

9、查询所有课程成绩小于60分的学生的学号、姓名

# 同2.1题
## 【所有】这个条件使用边界值进行限定
SELECT DISTINCT st.s_id, st.s_name
FROM Student st 
JOIN 
		(
		SELECT s_id, 
					 MIN(s_score) min_score
		FROM Score s
		GROUP BY s.s_id
		HAVING min_score < 60
		) s # 满足条件的学生
ON st.s_id = s.s_id

**10、查询没有学全所有课的学生的学号、姓名 **

SELECT
	stu.s_id,
	stu.s_name 
FROM
	student stu 
WHERE
	stu.s_id NOT IN ( SELECT s_id FROM score GROUP BY s_id HAVING COUNT( c_id ) = 3 )

11、查询至少有一门课与学号为“01”的学生所学课程相同的学生的学号和姓名

SELECT DISTINCT
	stu.s_id,
	stu.s_name 
FROM
	student stu
	LEFT JOIN score ON stu.s_id = score.s_id 
WHERE
	score.c_id IN ( SELECT c_id FROM score WHERE s_id = '01' ) 
	AND stu.s_id != '01'

12、查询和“01”号同学所学课程完全相同的其他同学的学号(重点!)

# 查找数量等于01学生的课程数量,再查询与01不相同的学生再取反
# 感觉不严谨。。。
SELECT DISTINCT
	s_id 
FROM
	score 
WHERE
	s_id IN (
SELECT
	s_id 
FROM
	score 
WHERE
	s_id != '01' 
GROUP BY
	s_id 
HAVING
	COUNT( DISTINCT c_id ) = ( SELECT count( DISTINCT c_id ) FROM score WHERE s_id = '01' ) 
	) 
	AND s_id NOT IN ( SELECT DISTINCT s_id FROM score WHERE c_id NOT IN ( SELECT c_id FROM score WHERE s_id = '01' ) )

group_concat函数

SELECT
	s_id 
FROM
	(
SELECT
	s_id,
	GROUP_CONCAT( c_id ORDER BY c_id ) a 
FROM
	score 
WHERE
	s_id != '01' 
GROUP BY
	s_id 
HAVING
	a = ( SELECT GROUP_CONCAT( c_id ORDER BY c_id ) a FROM score WHERE s_id = '01' GROUP BY s_id ) 
	) t

13、查询没学过"张三"老师讲授的任一门课程的学生姓名

SELECT DISTINCT
	s_id 
FROM
	score 
WHERE
	s_id NOT IN (
SELECT DISTINCT
	s_id 
FROM
	score 
WHERE
	c_id IN ( SELECT c_id FROM course WHERE t_id = ( SELECT t_id FROM teacher WHERE t_name = '张三' ) ) 
	)

15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩

SELECT
	sc.s_id,
	st.s_name,
	AVG( sc.s_score ) 
FROM
	score sc
	JOIN student st ON sc.s_id = st.s_id 
WHERE
	sc.s_id IN ( SELECT s_id FROM score WHERE s_score < 60 GROUP BY s_id HAVING COUNT( s_score ) >= 2 ) 
GROUP BY
	sc.s_id

16、检索"01"课程分数小于60,按分数降序排列的学生信息

SELECT
	score.s_id,
	s_name 
FROM
	score
	JOIN student ON score.s_id = student.s_id 
WHERE
	c_id = '01' 
	AND s_score < 60 
ORDER BY
	s_score DESC

17、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩

SELECT
	sc.s_id,
	sc.s_score,
	t.avgscore 
FROM
	score sc
	JOIN ( SELECT s_id, AVG( s_score ) avgscore FROM score GROUP BY s_id ) t ON sc.s_id = t.s_id 
ORDER BY
	t.avgscore DESC

18、查询各科成绩最高分、最低分和平均分:

以如下形式显示:

– 课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
– (及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90) (!!)

SELECT
	course.c_name,
	tem2.*,
	tem1.maxscore,
	tem1.minscore,
	tem1.avgscore 
FROM
	( SELECT c_id, MAX( s_score ) maxscore, MIN( s_score ) minscore, AVG( s_score ) avgscore FROM score GROUP BY c_id ) tem1
	JOIN (
SELECT
	p1.c_id,
	p2.sum_jige / p1.count jige_rate,
	p2.sum_zhongdeng / p1.count zhongdeng_rate,
	p2.sum_youliang / p1.count youliang_rate,
	p2.sum_youxiu / p1.count youxiu_rate 
FROM
	( SELECT c_id, COUNT( s_score ) count FROM score GROUP BY c_id ) p1
	JOIN (
SELECT
	t1.c_id c_id,
	SUM( t1.jige ) sum_jige,
	SUM( t1.zhongdeng ) sum_zhongdeng,
	SUM( t1.youliang ) sum_youliang,
	SUM( youxiu ) sum_youxiu 
FROM
	(
SELECT
	c_id,
IF
	( s_score >= 60 AND s_score < 70, 1, 0 ) jige,
IF
	( s_score >= 70 AND s_score < 80, 1, 0 ) zhongdeng,
IF
	( s_score >= 80 AND s_score < 90, 1, 0 ) youliang,
IF
	( s_score >= 90, 1, 0 ) youxiu 
FROM
	score 
	) t1 
GROUP BY
	t1.c_id 
	) p2 ON p1.c_id = p2.c_id 
	) tem2 ON tem1.c_id = tem2.c_id
	JOIN course ON tem1.c_id = course.c_id

19、按各科成绩进行排序,并显示排名

使用Row_number()和Rank()实现

SELECT
	*,
	DENSE_RANK ( ) over ( PARTITION BY c_id ORDER BY s_score DESC ) rk_score 
FROM
	score

20、查询学生的总成绩并进行排名

SELECT
	*,
	dense_rank ( ) over ( ORDER BY sumscore DESC ) 
FROM
	( SELECT s_id, SUM( s_score ) sumscore FROM score GROUP BY s_id ) t

21 、查询不同老师所教不同课程平均分从高到低显示

SELECT
	teacher.t_name,
	course.c_name,
	t.avgscore 
FROM
	course
	JOIN ( SELECT c_id, AVG( s_score ) avgscore FROM score GROUP BY c_id ) t ON course.c_id = t.c_id
	JOIN teacher ON course.t_id = teacher.t_id 
ORDER BY
	t.avgscore DESC

22、查询所有课程的成绩第2名到第3名的学生信息及该课程成绩

SELECT DISTINCT
	stu.s_name,
	cor.c_name,
	t.s_score,
	t.rk 
FROM
	( SELECT c_id, s_id, s_score, dense_rank ( ) over ( PARTITION BY c_id ORDER BY s_score DESC ) AS rk FROM score ) t
	JOIN student stu ON t.s_id = stu.s_id
	JOIN course cor ON cor.c_id = t.c_id 
WHERE
	t.rk IN ( 2, 3 )

23、使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,分别统计各分数段人数:课程ID和课程名称

MySQL case语句

SELECT
	course.c_name,
	p.* 
FROM
	course
	JOIN (
SELECT
	t.c_id,
	SUM( IF ( t.LEVEL = 'level1', 1, 0 ) ) '[100-85]',
	SUM( IF ( t.LEVEL = 'level2', 1, 0 ) ) '[85-70]',
	SUM( IF ( t.LEVEL = 'level3', 1, 0 ) ) '[70-60]',
	SUM( IF ( t.LEVEL = 'level4', 1, 0 ) ) '[<60]',
	COUNT( t.s_id ) sumstu 
FROM
	(
SELECT
	c_id,
	s_id,
	s_score,
CASE
	
	WHEN s_score BETWEEN 85 
	AND 100 THEN
	'level1' 
WHEN s_score BETWEEN 70 
AND 85 THEN
'level2' 
WHEN s_score BETWEEN 60 
AND 70 THEN
'level3' ELSE 'level4' 
END LEVEL 
FROM
	score 
	) t 
GROUP BY
	t.c_id 
) p ON course.c_id = p.c_id

24、查询学生平均成绩及其名次

SELECT
	*,
	dense_rank ( ) over ( ORDER BY t.avgscore DESC ) rk 
FROM
	(
SELECT
	stu.s_name,
	AVG( sc.s_score ) avgscore 
FROM
	student stu
	JOIN score sc ON stu.s_id = sc.s_id 
GROUP BY
	sc.s_id 
	) t

25、查询各科成绩前三名的记录(不考虑成绩并列情况)

SELECT
	t.* 
FROM
	( SELECT c_id, s_id, s_score, row_number ( ) over ( PARTITION BY c_id ORDER BY s_score DESC ) rk FROM score ) t 
WHERE
	t.rk IN ( 1, 2, 3 )

26、查询每门课程被选修的学生数

SELECT
	course.c_name,
	COUNT( score.s_id ) stucount 
FROM
	score
	JOIN course ON score.c_id = course.c_id 
GROUP BY
	course.c_name

27、查询出只有两门课程的全部学生的学号和姓名

SELECT
	student.s_id,
	student.s_name 
FROM
	student
	JOIN score ON student.s_id = score.s_id 
GROUP BY
	s_id 
HAVING
	count( c_id ) =2

28、查询男生、女生人数

SELECT
	s_sex,
	COUNT( s_id ) 
FROM
	student 
GROUP BY
	s_sex

29、查询名字中含有"风"字的学生信息

SELECT
	* 
FROM
	student 
WHERE
	s_name LIKE '%风%'

31、查询1990年出生的学生名单

SELECT
	* 
FROM
	student 
WHERE
	s_birth LIKE '%1990%'
-- -------------or----------------------
SELECT
	* 
FROM
	Student 
WHERE
	YEAR ( s_birth ) = '1990'

32、查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩

SELECT
	t.s_id,
	stu.s_name,
	t.avgscore 
FROM
	student stu
	RIGHT JOIN ( SELECT s_id, AVG( s_score ) avgscore FROM score GROUP BY s_id HAVING avgscore >= 85 ) t ON stu.s_id = t.s_id

33、查询每门课程的平均成绩,结果按平均成绩升序排序,平均成绩相同时,按课程号降序排列

(1)在MySql中,使用 ASC 或 DESC 关键字来设置查询结果是按升序或降序排列。

(2)尤其非常特别重要:默认按升序(ASC)排列

(3)order by 后可加2个(或多个)字段,字段之间用英文逗号隔开。

(4)若A用升序,B用降序,SQL该这样写:order by A ASC, B DESC; 默认同理,也可以这样写:order by A, B DESC;

(5)若A、B都用降序,必须用两个DESC,order by A DESC, B DESC;

(6)多个字段时,优先级按先后顺序而定。

SELECT
	c_id,
	AVG( s_score ) avgscore 
FROM
	score 
GROUP BY
	c_id 
ORDER BY
	avgscore ASC,
	c_id DESC

34、查询课程名称为"数学",且分数低于60的学生姓名和分数

SELECT
	stu.s_name,
	t.s_score 
FROM
	student stu
	JOIN ( SELECT s_id, s_score FROM score WHERE c_id = ( SELECT c_id FROM course WHERE c_name = '数学' ) AND s_score < 60 ) t ON stu.s_id = t.s_id

35、查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)

SELECT
	stu.s_name,
	co.c_name,
	sc.s_score 
FROM
	student stu
	LEFT JOIN score sc ON stu.s_id = sc.s_id
	LEFT JOIN course co ON sc.c_id = co.c_id

36、查询任何一门课程成绩在70分以上的姓名、课程名称和分数

SELECT
	stu.s_name,
	co.c_name,
	sc.s_score 
FROM
	student stu
	LEFT JOIN score sc ON stu.s_id = sc.s_id
	LEFT JOIN course co ON sc.c_id = co.c_id 
WHERE
	sc.s_id IN ( SELECT s_id FROM score GROUP BY s_id HAVING MAX( s_score ) > 70 )

37、查询学生不及格的课程并按课程号从大到小排列

SELECT
	* 
FROM
	score 
WHERE
	s_score < 60 
ORDER BY
	c_id DESC

38、查询课程编号为03且课程成绩在80分以上的学生的学号和姓名

SELECT
	s_id,
	s_name 
FROM
	student 
WHERE
	s_id IN ( SELECT s_id FROM score WHERE c_id = '03' AND s_score > 80 )

39、求每门课程的学生人数

SELECT
	co.c_name,
	t.stucount 
FROM
	course co
	JOIN ( SELECT c_id, COUNT( s_id ) stucount FROM score GROUP BY c_id ) t ON co.c_id = t.c_id

40、查询选修“张三”老师所授课程的学生中成绩最高的学生姓名及其成绩

SELECT
	stu.s_name,
	t.maxscore 
FROM
	student stu
	JOIN (
SELECT
	s_id,
	MAX( s_score ) maxscore 
FROM
	score 
WHERE
	c_id IN ( SELECT c_id FROM course JOIN teacher ON course.t_id = teacher.t_id WHERE teacher.t_name = '张三' ) 
	) t ON stu.s_id = t.s_id

41.查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩

-- 自连接
SELECT
	sc1.s_id,
	sc1.c_id,
	sc1.s_score 
FROM
	score sc1
	JOIN score sc2 ON sc1.s_score = sc2.s_score 
	AND sc1.s_id != sc2.s_id 
	AND sc1.c_id != sc2.c_id

42、查询每门课成绩最好的前两名

SELECT
	* 
FROM
	( SELECT c_id, s_id, row_number ( ) over ( PARTITION BY c_id ORDER BY s_score DESC ) scrank FROM score ) t 
WHERE
	t.scrank < 3

43、统计每门课程的学生选修人数(超过5人的课程才统计)

– 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列

SELECT
	course.c_name,
	t.* 
FROM
	( SELECT c_id, COUNT( s_id ) count FROM score GROUP BY c_id HAVING count > 5 ) t
	JOIN course 
WHERE
	course.c_id = t.c_id 
ORDER BY
	t.c_id

44、检索至少选修两门课程的学生学号

SELECT
	s_id,
	COUNT( c_id ) count 
FROM
	score 
GROUP BY
	s_id 
HAVING
	count >=2

45、查询选修了全部课程的学生信息

SELECT
	s_id,
	COUNT( c_id ) count 
FROM
	score 
GROUP BY
	s_id 
HAVING
	count = ( SELECT COUNT( DISTINCT c_id ) count FROM score )

46、查询各学生的年龄(精确到月份)

mysql获取当前时间

SELECT
	s_name,
IF
	(
	WEEK ( CURRENT_DATE ) >= WEEK ( s_birth ),
	YEAR ( CURRENT_DATE ) - YEAR ( s_birth ),
	YEAR ( CURRENT_DATE ) - YEAR ( s_birth ) - 1 
	) s_age 
FROM
	student

47、查询没学过“张三”老师讲授的任一门课程的学生姓名

SELECT
	s_name 
FROM
	student 
WHERE
	s_id NOT IN (
SELECT DISTINCT
	s_id 
FROM
	score 
WHERE
	c_id IN ( SELECT c_id FROM course WHERE t_id = ( SELECT t_id FROM teacher WHERE t_name = '张三' ) ) 
	)

48、查询两门以上不及格课程的同学的学号及其平均成绩

SELECT
	s_id,
	AVG( s_score ) 
FROM
	score 
WHERE
	s_id IN (
SELECT
	t.s_id 
FROM
	( SELECT s_id, s_score FROM score WHERE s_score < 60 ) t 
GROUP BY
	t.s_id 
HAVING
	COUNT( t.s_score ) > 2 
	)

49、查询本月过生日的学生

SELECT
	s_name 
FROM
	student 
WHERE
	MONTH ( s_birth ) = MONTH ( CURRENT_DATE )

49.1、查询下月过生日的学生

MySQL If(函数)

-- 考虑12月的下一月应该是1月的情况
SELECT
	s_name 
FROM
	student 
WHERE
	MONTH ( s_birth ) = ( SELECT IF ( MONTH ( CURRENT_DATE ) = 12, 1, MONTH ( CURRENT_DATE ) + 1 ) )

50、查询本周过生日的学生

SELECT
	s_name 
FROM
	student 
WHERE
	WEEK ( s_birth ) = ( SELECT WEEK ( CURRENT_DATE ) )

50.1、查询下周过生日的学生

MySQL间隔值主要用于日期和时间计算

-- 用interval来解决期末与期初的问题
SELECT
	s_name 
FROM
	student 
WHERE
	WEEK ( s_birth ) = ( SELECT WEEK ( CURRENT_DATE + INTERVAL 1 WEEK ) )

  • 12
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值