单表查询
多表查询
第1章 多表查询套路
1.多表查询的套路
第一步: 先分析题意 找出需要哪些表
第二步: 找出这些表之间的关联关系
第三步: 将这些表联合成一张大表
第四步: 对这个大表在做查询
2.多表关联技巧
两张表有直接关系:
select *
from a
join b
on a.num1 = b.num1
两张表没有直接关系,通过第三张表关联:
select *
from a
join b
on a.num1 = b.num1
join c
on b.num2 = c.num2
第2章 练习题
0.关联模板
SELECT *
FROM 第一张表
JOIN 第二张表
ON 第一张表.字段 = 第二张表.字段
1.显示老师名字和他教的课程名称
第一步: 先分析题意 找出需要哪些表
teacher
course
第二步: 找出这些表之间的关联关系
teacher.tno = course.tno
第三步: 将这些表联合成一张大表
select *
from teacher
join course
on teacher.tno = course.tno
第四步: 对这个大表在做查询
SELECT teacher.tname,course.cname
FROM teacher
JOIN course
ON teacher.tno = course.tno
SELECT tname,cname FROM course
JOIN teacher
ON course.tno = teacher.tno
2.统计每个学员的姓名及其学习课程的门数,并且打印出学的课程名称
第一步: 先分析题意 找出需要哪些表
student sc course
第二步: 找出这些表之间的关联关系
student.sno = sc.sno
sc.cno = course.cno
第三步: 将这些表联合成一张大表
SELECT *
FROM student
JOIN sc
ON student.sno = sc.sno
JOIN course
ON sc.cno = course.cno
第四步: 对这个大表在做查询
SELECT student.sno'学号',student.sname'学生姓名',COUNT(sc.cno)'课程门数',GROUP_CONCAT(course.cname)'课程名称'
FROM student
JOIN sc
ON student.sno = sc.sno
JOIN course
ON sc.cno = course.cno
GROUP BY student.sno
SELECT sc.sno'学号',student.sname'学生姓名',COUNT(course.cname)'课程门数',GROUP_CONCAT(course.cname)'课程名称' FROM
course
JOIN sc
ON course.cno=sc.cno
JOIN student
ON sc.sno=student.sno
GROUP BY sc.sno
3.每位老师姓名及其教的学生数量和学生名列表
select *
from teacher
join course
on teacher.tno = course.tno
join sc
on course.cno = sc.cno
join student
on sc.sno = student.sno
3.每位老师姓名及其教的学生数量和学生名列表
SELECT course.cname'课程名称',teacher.tname'老师姓名',COUNT(student.sno)'学生数量',GROUP_CONCAT(student.sname)'学生名单'
FROM teacher
JOIN course
ON teacher.tno = course.tno
JOIN sc
ON course.cno = sc.cno
JOIN student
ON sc.sno = student.sno
GROUP BY teacher.tno,course.cname
SELECT teacher.tno'教师号码',teacher.tname'教师姓名',COUNT(student.sname)'学生数量',GROUP_CONCAT(student.sname)'学生名列表' FROM
course
JOIN sc
ON course.cno=sc.cno
JOIN student
ON sc.sno=student.sno
JOIN teacher
ON course.tno=teacher.tno
GROUP BY teacher.tno
4.每位老师教所教课程的平均分.最高分以及最低分
SELECT teacher.tname'老师姓名',course.cname'课程名称',AVG(sc.score)'平均分',MAX(sc.score)'最高分',MIN(sc.score)'最低分'
FROM teacher
JOIN course
ON teacher.tno = course.tno
JOIN sc
ON course.cno = sc.cno
GROUP BY teacher.tno,course.cname
SELECT teacher.tno'教师编号',teacher.tname'教师姓名',course.cname'课程名称',AVG(sc.score)'课程平均分',MAX(sc.score)'课程最高分',MIN(sc.score)'课程最低分' FROM
course
JOIN sc
ON course.cno=sc.cno
JOIN teacher
ON course.tno=teacher.tno
GROUP BY teacher.tno,teacher.tname,course.cname
5.查找学习了hesw但没学习oldguo课程的学生名
方法1:
SELECT student.sname,GROUP_CONCAT(teacher.tname)
FROM teacher
JOIN course
ON teacher.tno = course.tno
JOIN sc
ON course.cno = sc.cno
JOIN student
ON sc.sno = student.sno
GROUP BY student.sno
HAVING GROUP_CONCAT(teacher.tname) LIKE '%hesw%'
AND
GROUP_CONCAT(teacher.tname) NOT LIKE '%oldguo%'
SELECT student.sname'学生姓名',GROUP_CONCAT(teacher.tname)'老师姓名' FROM
course
JOIN sc
ON course.cno=sc.cno
JOIN student
ON sc.sno=student.sno
JOIN teacher
ON course.tno=teacher.tno
GROUP BY student.sname
HAVING GROUP_CONCAT(teacher.tname) LIKE '%hesw%'
AND
GROUP_CONCAT(teacher.tname) NOT LIKE '%oldguo%'
方法2:
6.查询出只选修了一门课程的全部学生的学号和姓名
SELECT student.sno'学号',student.sname'学生姓名',COUNT(sc.cno)'课程门数',GROUP_CONCAT(course.cname)'课程名称'
FROM student
JOIN sc
ON student.sno = sc.sno
JOIN course
ON sc.cno = course.cno
GROUP BY student.sno
HAVING COUNT(sc.cno) = 1
SELECT sc.sno'学号',student.sname'学生姓名',COUNT(course.cname)'课程数',GROUP_CONCAT(course.cname)'课程名称' FROM
course
JOIN sc
ON course.cno=sc.cno
JOIN student
ON sc.sno=student.sno
GROUP BY sc.sno,student.sname
HAVING COUNT(course.cname)=1
7.查询平均成绩大于85的所有学生的学号、姓名和平均成绩
SELECT student.sno,student.sname,AVG(sc.score)
FROM student
JOIN sc
ON student.sno = sc.sno
GROUP BY student.sno
HAVING AVG(sc.score) > 85
SELECT sc.sno,student.sname,AVG(sc.score) FROM
sc
JOIN student
ON sc.sno=student.sno
GROUP BY sc.sno,student.sname
HAVING AVG(sc.score) >85
8.统计每门课程: 优秀(85分以上),良好(70-85),一般(60-70),不及格(小于60)的学生列表
SELECT
course.cname'课程名称',
GROUP_CONCAT(CASE WHEN sc.score >85 THEN CONCAT(student.sname,':',sc.score) END)'优秀',
GROUP_CONCAT(CASE WHEN sc.score > 70 AND sc.score < 85 THEN CONCAT(student.sname,':',sc.score) END)'良好',
GROUP_CONCAT(CASE WHEN sc.score > 60 AND sc.score < 70 THEN CONCAT(student.sname,':',sc.score) END)'及格',
GROUP_CONCAT(CASE WHEN sc.score < 60 THEN CONCAT(student.sname,':',sc.score) END)'不及格'
FROM student
JOIN sc
ON student.sno = sc.sno
JOIN course
ON course.cno = sc.cno
GROUP BY course.cname
SELECT
course.cname'课程名称',
GROUP_CONCAT(CASE WHEN sc.score >85 THEN CONCAT(student.sname,':',sc.score) END)'优秀',
GROUP_CONCAT(CASE WHEN sc.score > 70 AND sc.score < 85 THEN CONCAT(student.sname,':',sc.score) END)'良好',
GROUP_CONCAT(CASE WHEN sc.score > 60 AND sc.score < 70 THEN CONCAT(student.sname,':',sc.score) END)'及格',
GROUP_CONCAT(CASE WHEN sc.score < 60 THEN CONCAT(student.sname,':',sc.score) END)'不及格'
FROM student as s
JOIN sc as b
ON s.sno = b.sno
JOIN course as c
ON c.cno = b.cno
GROUP BY c.cname
SELECT course.cname'课程名称',
GROUP_CONCAT(CASE WHEN sc.score >85 THEN student.sname END)'优秀',
GROUP_CONCAT(CASE WHEN sc.score >=70 AND sc.score <=85 THEN student.sname END)'良好',
GROUP_CONCAT(CASE WHEN sc.score >=60 AND sc.score < 70 THEN student.sname END)'一般',
GROUP_CONCAT(CASE WHEN sc.score < 60 THEN student.sname END)'不及格'
FROM
course
JOIN sc
ON course.cno=sc.cno
JOIN student
ON sc.sno=student.sno
GROUP BY course.cname
设置成名字加分数显示
使用concat
MySQL中concat函数
MySQL的concat函数可以连接一个或者多个字符串
CONCAT(student.sname,':',sc.score)
SELECT course.cname'课程名称',
GROUP_CONCAT(CASE WHEN sc.score >85 THEN CONCAT(student.sname,':',sc.score) END)'优秀',
GROUP_CONCAT(CASE WHEN sc.score >=70 AND sc.score <=85 THEN CONCAT(student.sname,':',sc.score) END)'良好',
GROUP_CONCAT(CASE WHEN sc.score >=60 AND sc.score < 70 THEN CONCAT(student.sname,':',sc.score) END)'一般',
GROUP_CONCAT(CASE WHEN sc.score < 60 THEN CONCAT(student.sname,':',sc.score) END)'不及格'
FROM
course
JOIN sc
ON course.cno=sc.cno
JOIN student
ON sc.sno=student.sno
GROUP BY course.cname
MySQL 数据的表设置别名
AS
SELECT * FROM
course
JOIN sc
ON course.cno=sc.cno
JOIN student
ON sc.sno=student.sno
改写
SELECT * FROM
course AS c
JOIN sc AS s
ON c.cno=s.cno
JOIN student AS st
ON s.sno=st.sno