SELECT
t1.*,
t2.score,
t3.score
FROM student t1,score t2,score t3
WHERE t2.c_id='01'AND t3.c_id='02'AND t2.score>t3.score
AND t1.s_id=t2.s_id
AND t1.s_id=t3.s_id
sql ='SELECT t1.*,t2.score,t3.score FROM student t1,score t2,score t3 WHERE t2.c_id="01" AND t3.c_id="02" AND t2.score>t3.score AND t1.s_id=t2.s_id AND t1.s_id=t3.s_id'
df = pd.read_sql(sql, eng)
df
s_id
s_name
s_birthday
s_sex
score
score
0
02
钱电
1990-12-21
男
70.0
60.0
1
04
李云
1990-08-06
男
50.0
30.0
1.2 查询存在 01 课程但可能不存在 02 课程的情况 (不存在时显示为 NULL)
SELECT*FROM student t1
LEFTJOIN score t2 ON t1.s_id=t2.s_id AND t2.c_id='01'LEFTJOIN score t3 ON t1.s_id=t3.s_id AND t3.c_id='02'AND t2.score>t3.score
AND t2.s_id ISNOTNULL;
SELECT
t1.*FROM student t1, teacher t2,course t3,score t4
WHERE t1.s_id=t4.s_id
AND t4.c_id=t3.c_id
AND t3.t_id=t2.t_id
AND t2.t_name='张三';
s_id
s_name
s_birthday
s_sex
0
01
赵雷
1990-01-01
男
1
02
钱电
1990-12-21
男
2
03
孙风
1990-05-20
男
3
04
李云
1990-08-06
男
4
05
周梅
1991-12-01
女
5
07
郑竹
1989-07-01
女
7.查询没有学全所有课程的同学的信息
SELECT*FROM student
WHERE s_id NOTIN(SELECT
s_id
FROM score
GROUPBY s_id
HAVINGCOUNT(sc.c_id)=(SELECTCOUNT(c_id)FROM course
));
s_id
s_name
s_birthday
s_sex
0
05
周梅
1991-12-01
女
1
06
吴兰
1992-03-01
女
2
07
郑竹
1989-07-01
女
3
09
张三
2017-12-20
女
4
10
李四
2017-12-25
女
5
11
李四
2017-12-30
女
6
12
赵六
2017-01-01
女
7
13
孙七
2018-01-01
女
8.查询至少有一门课与学号为 “01” 的同学所学相同的同学的信息
解法一
SELECT*FROM student
WHEREs_id IN(SELECT
t2.s_id
FROM score t2
WHERE t2.c_id IN(SELECT
t2.c_id
FROM score t2
WHERE t2.s_id ='01'))
解法2
SELECTDISTINCT t1.*FROM student t1, score t2
WHERE t1.s_id = t2.s_id
AND t2.c_id IN(SELECT
t2.c_id
FROM score t2
WHERE t2.s_id ='01')AND t1.s_id <>'01';|| s_id | s_name | s_birthday | s_sex ||-|--- | ------ | ---------- | ----- ||0|01| 赵雷 |1990-01-01| 男 ||1|02| 钱电 |1990-12-21| 男 ||2|03| 孙风 |1990-05-20| 男 ||3|04| 李云 |1990-08-06| 男 ||4|05| 周梅 |1991-12-01| 女 ||5|06| 吴兰 |1992-03-01| 女 ||6|07| 郑竹 |1989-07-01| 女 |##### **9. 查询和 "01" 号的同学学习的课程完全相同的其他同学的信息*** 解法1```sqlSELECTDISTINCT t1.*FROM student t1,score t2
WHERE t1.s_id = t2.s_id
AND t1.s_id <>'01'AND t2.c_id IN(SELECTDISTINCT t3.c_id
FROM score t3
WHERE t3.s_id ='01')
解法二
SELECT
student.*FROM student
WHERE s_id IN(SELECTDISTINCT sc.s_id
FROM sc
WHERE s_id <>'01'AND sc.c_id IN(SELECT
c_id
FROM sc
WHEREs_id ='01'));
s_id
s_name
s_birthday
s_sex
0
02
钱电
1990-12-21
男
1
03
孙风
1990-05-20
男
2
04
李云
1990-08-06
男
3
05
周梅
1991-12-01
女
4
06
吴兰
1992-03-01
女
5
07
郑竹
1989-07-01
女
10. 查询没学过 “张三” 老师讲授的任一门课程的学生姓名
解法一
SELECTDISTINCT t1.s_name
FROM student t1
WHERE t1.s_id NOTIN(SELECT
t2.s_id
FROM score t2, course t3
WHERE t2.c_id = t3.c_id
AND t3.t_id IN(SELECT
t4.t_id
FROM teacher t4
WHEREt_name ='张三'));
解法二
SELECTDISTINCT t1.s_name
FROM student t1
WHERE t1.s_id NOTIN(SELECT
t2.s_id
FROM score t2, course t3, teacher t4
WHEREt2.c_id = t3.c_id
AND t3.t_id = t4.t_id
AND t4.t_name ='张三');
s_name
0
吴兰
1
张三
2
李四
3
赵六
4
孙七
11.查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
SELECT
t1.s_id,
t1.s_name,AVG(t2.score)FROM student t1,score t2
WHERE t1.s_id = t2.s_id
AND t2.score <60GROUPBY t2.s_id
HAVINGCOUNT(*)>=2;
s_id
s_name
AVG(t2.score)
0
04
李云
1
06
吴兰
12.检索 “01” 课程分数小于 60,按分数降序排列的学生信息
SELECT
t1.*,
t2.score
FROM student t1,score t2
WHERE t1.s_id = t2.s_id
AND t2.c_id ='01'AND score <60ORDERBY t2.score DESC;
s_id
s_name
s_birthday
s_sex
score
0
04
李云
1990-08-06
男
50.0
1
06
吴兰
1992-03-01
女
31.0
13. 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
SELECT
t1.*,
t3.avgscore
FROM score t1
LEFTJOIN(SELECT
t2.s_id,AVG(t2.score)AS avgscore
FROM score t2
GROUPBY t2.s_id
)AS t3 ON t1.s_id = t3.s_id
ORDERBY t3.avgscore DESC;
SELECT*,COUNT(*)FROM student
WHEREs_name IN(SELECT
s_name
FROM student
GROUPBY s_name
HAVINGCOUNT(*)>1);
s_id
s_name
s_birthday
s_sex
COUNT(*)
0
10
李四
2017-12-25
女
2
24. 查询 1990 年出生的学生名单
SELECT*FROM student
WHEREYEAR(s_birthday)=1990;
s_id
s_name
s_birthday
s_sex
0
01
赵雷
1990-01-01
男
1
02
钱电
1990-12-21
男
2
03
孙风
1990-05-20
男
3
04
李云
1990-08-06
男
25.查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
解法一
SELECT
t1.s_id,
t1.s_name,AVG(t2.score)AS 平均成绩
FROM student t1, score t2
WHERE t1.s_id = t2.s_id
GROUPBY t2.s_id
HAVINGAVG(t2.score)>=85;
解法二
SELECT
t1.s_id,
t1.s_name,AVG(t2.score)AS 平均成绩
FROM student t1
LEFTJOIN score t2 ON t1.s_id = t2.s_id
GROUPBY t2.s_id
HAVINGAVG(t2.score)>=85;
s_id
s_name
平均成绩
0
01
赵雷
89.66667
1
07
郑竹
94.00000
26.查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩
SELECT
t1.sid AS 学号,
t1.s_name AS 姓名,AVG(t2.score)AS 平均成绩
FROM student t1
LEFTJOIN sc t2 ON t1.sid = t2.sid
GROUPBY t1.sid
HAVING 平均成绩 >=85;
sql ='SELECT t1.s_id, t1.s_name, AVG(t2.score) AS 平均成绩 FROM student t1, score t2 WHERE t1.s_id = t2.s_id GROUP BY t2.s_id HAVING AVG(t2.score) >= 85'
df = pd.read_sql(sql, eng)
df
s_id
s_name
平均成绩
0
01
赵雷
89.66667
1
07
郑竹
93.50000
27. 查询课程名称为「数学」,且分数低于 60 的学生姓名和分数
解法一:
SELECT
t1.s_name AS 学生姓名,
t3.c_name AS 课程,
t2.score AS 分数
FROM student t1
LEFTJOIN score t2 ON t1.s_id = t2.s_id
LEFTJOIN course t3 ON t2.c_id = t3.c_id
WHEREt3.c_name ='数学'AND t2.score <60;
解法二:
SELECT
t1.s_name AS 学生姓名,
t3.c_name AS 课程,
t2.score AS 分数
FROM student t1, score t2, course t3
WHERE t1.s_id = t2.s_id
AND t2.c_id = t3.c_id
AND t3.c_name ='数学'AND t2.score <60;
学生姓名
课程
分数
0
李云
数学
30.0
28. 查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
SELECT
t1.s_id AS 学号,
t1.s_name AS 姓名,
t3.c_name AS 课程,
t2.c_id AS 课程编号,
t2.score AS 分数
FROM student t1
LEFTJOIN score t2 ON t1.s_id = t2.s_id
LEFTJOIN course t3 ON t2.c_id = t3.c_id
ORDERBY t1.s_id, t2.c_id;
表格较长,只截取部分
学号
姓名
课程
课程编号
分数
0
01
赵雷
语文
01
80.0
1
01
赵雷
数学
02
90.0
2
01
赵雷
英语
03
99.0
29. 查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数
解法一
SELECT
t1.s_name AS 姓名,
t3.c_name AS 课程,
t2.score AS 分数
FROM student t1
LEFTJOIN score t2 ON t1.s_id = t2.s_id
LEFTJOIN course t3 ON t2.c_id=t3.c_id
WHEREt2.score >70ORDERBY 姓名;
解法二
SELECT
t1.s_name AS 姓名,
t3.c_name AS 课程,
t2.score AS 分数
FROM student t1, score t2, course t3
WHEREt2.score >70AND t2.c_id = t3.c_id
AND t1.s_id = t2.s_id
ORDERBY 姓名;
表格较长,只截取部分
姓名
课程
分数
0
周梅
数学
87.0
1
周梅
语文
76.0
2
孙风
英语
80.0
3
孙风
数学
80.0
30. 查询存在不及格的课程
SELECT
t1.c_id AS 课程编号,
t1.c_name AS 课程名
FROM course t1
LEFTJOIN score t2 ON t1.c_id = t2.c_id
WHEREt2.score <60GROUPBY 课程名
ORDERBY 课程编号;#这里也可以不用 GROUP BY,而在 SELECT 后加 DITINCT 来取唯一
课程编号
课程名
0
01
语文
1
02
数学
2
03
英语
31. 查询课程编号为 01 且课程成绩在 80 分及以上的学生的学号和姓名
SELECT
t1.s_id AS 学号,
t1.s_name AS 姓名,
t2.c_id AS 课程编号,
t2.score AS 成绩
FROM student t1
LEFTJOIN score t2 ON t1.s_id = t2.s_id
WHEREt2.c_id ='01'AND t2.score >=80;
学号
姓名
课程编号
成绩
0
01
赵雷
01
80.0
1
03
孙风
01
80.0
32. 求每门课程的学生人数
SELECT
t1.c_id AS 课程编号,
t1.c_name AS 课程,COUNT(t2.s_id)AS 总人数
FROM course t1
LEFTJOIN score t2 ON t1.c_id = t2.c_id
GROUPBY t2.c_id;
课程编号
课程
总人数
0
01
语文
6
1
02
数学
6
2
03
英语
6
33. 成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
解法一:
SELECT
t1.*,
t4.t_name AS 教师,
t3.c_name AS 课程,MAX(T2.score)AS 分数
FROM student t1
LEFTJOIN score t2 ON t1.s_id = t2.s_id
LEFTJOIN course t3 ON t2.c_id = t3.c_id
LEFTJOIN teacher t4 ON t4.t_id = t3.t_id
WHEREt4.t_name ='张三';
解法二:
SELECT
t1.*,
t2.score,
t2.c_id
FROM student t1, score t2, course t3, teacher t4
WHEREt4.t_id = t3.t_id
AND t3.c_id = t2.c_id
AND t2.s_id = t1.s_id
AND t4.t_name ='张三'HAVINGMAX(t2.score);#‘HAVING MAX(t2.score)’ 也可以写成 ‘ORDER BY t2.score DEscore LIMIT 1’
s_id
s_name
s_birthday
s_sex
教师
课程
分数
0
01
赵雷
1990-01-01
男
张三
数学
90.0
34. 成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
为了验证,让数学有两个最高分
UPDATE score SET score =90 WHEREc_id ='02'AND s_id ='07';SELECT
t1.*,
t4.t_name AS 教师,
t3.c_name AS 课程,
T2.score AS 分数
FROM student t1
LEFTJOIN score t2 ON t1.s_id = t2.s_id
LEFTJOIN course t3 ON t2.c_id = t3.c_id
LEFTJOIN teacher t4 ON t4.t_id = t3.t_id
WHEREt4.t_name ='张三'AND t2.score =(SELECTMAX(t5.score)FROM score t5
LEFTJOIN course t6 ON t5.c_id = t6.c_id
LEFTJOIN teacher t7 ON t6.t_id = t7.t_id
WHERE t7.t_name ='张三');
s_id
s_name
s_birthday
s_sex
教师
课程
分数
0
01
赵雷
1990-01-01
男
张三
数学
90.0
1
07
郑竹
1989-07-01
女
张三
数学
90.0
35. 查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
先改个数方便验证:
UPDATE score SET score =30 WHEREs_id ='04'AND c_id ='03';SELECT
t1.s_id AS 学生编号,
t1.c_id AS 课程编号,
t1.score AS 学生成绩
FROM score t1
INNERJOIN score t2 ON t1.s_id = t2.s_id
WHEREt1.c_id != t2.c_id
AND t1.score = t2.score
GROUPBY t1.s_id;
学生编号
课程编号
学生成绩
0
03
03
80.0
36. 查询每门功课成绩最好的前两名
SELECT
t1.c_id AS 课程编号,
t2.c_name AS 课程名,
t1.s_id AS 学号,
t3.s_name AS 姓名,
t1.score AS 成绩
FROM score t1
LEFTJOIN course t2 ON t1.c_id = t2.c_id
LEFTJOIN student t3 ON t3.s_id = t1.s_id
WHERE(SELECTCOUNT(*)FROM score t4
WHEREt1.c_id = t4.c_id
AND t4.score > t1.score
)<2ORDERBY t1.c_id;
课程编号
课程名
学号
姓名
成绩
0
01
语文
01
赵雷
80.0
1
01
语文
03
孙风
80.0
2
02
数学
01
赵雷
90.0
3
02
数学
07
郑竹
89.0
4
03
英语
01
赵雷
99.0
5
03
英语
07
郑竹
98.0
37. 统计每门课程的学生选修人数(超过 5 人的课程才统计)
SELECT
t1.c_id AS 课程号,
t2.c_name AS 课程名,COUNT(t1.s_id)AS 选修人数
FROM score t1
LEFTJOIN course t2 ON t1.c_id = t2.c_id
GROUPBY t1.c_id
HAVINGCOUNT(t1.s_id)>4;
课程号
课程名
选修人数
0
01
语文
6
1
02
数学
6
2
03
英语
6
38. 检索至少选修两门课程的学生学号
SELECT
t1.s_id AS 学号,COUNT(t1.c_id)AS 选修数
FROM score t1
GROUPBY t1.s_id
HAVING 选修数 >=2;
学号
选修数
0
01
3
1
02
3
2
03
3
3
04
3
4
05
2
5
06
2
6
07
2
39. 查询选修了全部课程的学生信息
SELECT
t1.s_id AS 学号,
t1.s_name AS 姓名,
t1.s_birthday AS 出生年月,
t1.s_sex AS 性别
FROM student t1, score t2
WHEREt1.s_id = t2.s_id
GROUPBY t2.s_id
HAVINGCOUNT(t2.c_id)>=3;
学号
姓名
出生年月
性别
0
01
赵雷
1990-01-01
男
1
02
钱电
1990-12-21
男
2
03
孙风
1990-05-20
男
3
04
李云
1990-08-06
男
40. 查询各学生的年龄,只按年份来算
SELECT
t1.s_id AS 学号,
t1.s_name AS 姓名,
TIMESTAMPDIFF(YEAR,t1.s_birthday,CURDATE())AS 年龄
FROM student t1;#TIMESTAMPDIFF函数规范:https://blog.youkuaiyun.com/zmxiangde_88/article/details/8011661
表格较长,只截取部分
学号
姓名
年龄
0
01
赵雷
32
1
02
钱电
31
2
03
孙风
32
41. 按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一
SELECT
s_id,
s_name,(DATE_FORMAT(NOW(),'%Y')-DATE_FORMAT(s_birthday,'%Y')-(CASEwhen
DATE_FORMAT(NOW(),'%m%d')>DATE_FORMAT(s_birthday,'%m%d')then0else1END))AS age
FROM student;