多表查询
有两张表
课程表和老师表。
两个表之间的关系,是通过tid关联在一起
基本语法
select 字段名 from table1,table2
where table1.字段 = table2.字段 -- 两个表之间的关联
- 查询老师编号,姓名,所教授的课程名。 ```python
select course.tid,tname,cname from teacher,course where teacher.tid = course.tid; — 两个表之间的关联

2. 查询学生的姓名(sname)对应的成绩(score).

select sc.sid, sname,score FROM scholar,sc WHERE scholar.sid = sc.sid;

3. 查询学生的姓名,总分,并按照总分进行降序排序;
```sql
-- 查询学生的姓名,总分
SELECT sc.Sid,sname,sum(score) from scholar,sc
WHERE scholar.Sid=sc.Sid
GROUP BY sc.Sid
ORDER BY sum(score) DESC;
- 查询总分最高的同学姓名,总分; ```sql — 过滤最高分
select sum(score) from sc GROUP BY sid order by sum(score) desc LIMIT 1
— 根据最高分 找到对应的人员信息 SELECT sc.Sid,sname,sum(score) from scholar,sc WHERE scholar.Sid=sc.Sid GROUP BY sc.Sid having SUM(score) = ( select sum(score) from sc GROUP BY sid order by sum(score) desc LIMIT 1 )

4. 查询学号(sid), 学生姓名(sname),科目名称(cname),科目成绩(score);

```sql
select scholar.sid,sname,cname,score from scholar,sc,course
where sc.sid = scholar.sid and sc.cid = course.cid;
汇总每门课程课程名,总成绩,平均成绩,考试人数
select cname, sum(score), avg(score), count(1) from scholar,sc,course
where sc.sid = scholar.sid and sc.cid = course.cid
GROUP BY cname;
总结
在做多表查询的时候:
找到每个表之间对应的关系。关系写在 where 子句中。
- 后面的操作跟单表操作原理一样。
内联接 inner join
inner join 在连接多个表的时候主要过滤出来表中共同的数据。
使用 inner join 查询 学生姓名(sname),学生成绩(score);
select sname,score from scholar
inner join sc -- 连接表
on sc.sid = scholar.sid; -- 表之间的关联
使用 inner join 内连接 与上面使用 where 多表查询 效果一样。
查询学生姓名(sname),考试科目(cname),成绩(score);
select sname,cname,score from scholar
inner join sc
on scholar.sid = sc.sid
inner join course
on sc.cid = course.cid;
- 学生姓名(sname),考试科目(cname),对应老师姓名(tname),成绩(score);
SELECT sname, cname,tname,score from scholar
INNER JOIN sc
ON sc.Sid = scholar.Sid
INNER JOIN course
ON course.cid = sc.cid
INNER JOIN teacher
ON teacher.Tid = course.Tid;
左联结 left join
- 查询学生姓名,学生的成绩(如果学生没有对应的成绩,显示为Null)
select sname,score from scholar
left join sc
on scholar.sid = sc.sid;
- 查询张三同学的所有的考试科目(cname),成绩(score);
SELECT "张三" AS 姓名, cname 课程 ,score 成绩 from course
LEFT JOIN (SELECT * from sc WHERE sid in (SELECT sid from scholar WHERE sname="张三" )) as stu1
ON stu1.cid = course.cid
右联结 right join
跟 left join 效果一样,以右边的表为主表。
需要注意的是: Mysql 不支持 外连接;
组合查询union
union 可以将两个查询语句合并一张表中;
- 查询语文课程的总成绩,可以使用下面的sql ```sql SELECT course,sum(score) from students WHERE course = “语文” GROUP BY course

2. 查询数学课程的总成绩,可以使用下面的sql
```sql
SELECT course,sum(score) from students
WHERE course = "数学"
GROUP BY course
- 上面2条sql语句查询的结果可以合并在一起 ```sql SELECT course,sum(score) from students WHERE course = “语文” GROUP BY course
UNION — 连接两个数据
SELECT course,sum(score) from students WHERE course = “数学” GROUP BY course

<a name="pczMg"></a>
# 面试问题
1. 左联和内联的区别?
1. 怎么做多表联查?
<a name="SOmWb"></a>
# 思维导图

<a name="QIqWt"></a>
# 作业
根据下面4个表<br /><br />
---
1.查询姓"张"的学生名单;
```sql
select * from scholar
where sname like "张%";
2.查询平均成绩大于60分的同学的学号和平均成绩;
select sid, avg(score) from sc
group by sid
having avg(score) > 60;
3.查询所有同学的学号、姓名、选课数、总成绩;
select scholar.sid,sname,count(course.cid),sum(score) from scholar
inner join sc
on scholar.sid = sc.sid
inner join course
on course.cid = sc.cid
GROUP BY scholar.Sid,Sname
4.查询没学过王大锤
老师课的同学的学号、姓名;
-- 1. 找到王大锤老师的 课程id cid
select cid from course
inner join teacher
on course.tid = teacher.tid
where tname = "王大锤"
-- 2. 从成绩表中找到没有 王大锤的 cid的学号 sid
select DISTINCT(sid) from sc
where cid <> (
select cid from course
inner join teacher
on course.tid = teacher.tid
where tname = "王大锤"
)
-- 根据学号 可以找到姓名
SELECT sid,sname from scholar
WHERE sid in (
select DISTINCT(sid) from sc
where cid <> (
select cid from course
inner join teacher
on course.tid = teacher.tid
where tname = "王大锤"
)
);
5.查询每门课程被选修的学生数;
select cid, count(cid) from sc
group by cid;
-- 也可以
select (select course.Cname from course WHERE course.Cid =sc.Cid) as 科目, count(cid) 选修人数 from sc
group by cid;
7.查询学生名单,统计男生,女生人数;
select ssex,count(ssex) from scholar
group by ssex;
8.查询出只修了一门课程的全部学生的学号和姓名;
-- 1. 查找修一门课的学号 sid
SELECT sid from sc
GROUP BY sid
HAVING count(sid) = 1
-- 2. 根据学号 找人
select sid,sname from scholar
WHERE sid in (
SELECT sid from sc
GROUP BY sid
HAVING count(sid) = 1
)
9.统计每个同学的课程成绩,并按课程号从大到小排序列;
select sname,cname, score from scholar
inner join sc
on sc.sid = scholar.sid
inner join course
on course.cid = sc.cid
order by course.cid
10.语文成绩大于数学成绩的学生信息;
select scholar.sid 学号,sname 名字 from scholar
INNER JOIN sc
ON sc.sid = scholar.Sid
INNER JOIN course
ON sc.cid = course.Cid
-- 语文成绩 并且语文大于数学
WHERE cname = "语文" AND score > (
-- 查询数学成绩
SELECT 数学 from (select scholar.sid 学号,sname 名字,score 数学 from scholar
INNER JOIN sc
ON sc.sid = scholar.Sid
INNER JOIN course
ON sc.cid = course.Cid
WHERE cname = "数学") as math
WHERE 学号 = math.学号
);
1.查出平均成绩>85的学生学号,姓名,平均成绩;
select No,Name,avg(score) from students
group by No,Name
having avg(score) > 85;
2.在students表中 查询出每门课都大于80分的学生姓名;
-- 都大于80, 最低分大于80 即可
select no, name from students
group by no,name
having min(score) > 80;
3.查出平均成绩第一名的学生;
-- 最高的平均成绩
select avg(score) from students
group by No
order by avg(score) desc
limit 1
-- 根据成绩找人
select No,Name,avg(score) from students
group by No,Name
having avg(score) = (
select avg(score) from students
group by No
order by avg(score) desc
limit 1
);
4.查出所有语文成绩>数学成绩的学生学号,姓名,语文成绩,数学成绩;
select No,Name,
sum(case course when '语文' then score else 0 End) as '语文',
sum(case course when '数学' then score else 0 End) as '数学',
sum(case course when '英语' then score else 0 End) as '英语'
from students
GROUP BY No,Name
-- 在从上面生成的表中做查询
select * from
(select No,Name,
sum(case course when '语文' then score else 0 End) as '语文',
sum(case course when '数学' then score else 0 End) as '数学',
sum(case course when '英语' then score else 0 End) as '英语'
from students
GROUP BY No,Name) as tmp
where 语文>数学;
附件
https://pear-fall-0cf.notion.site/64874dc67957406ca99d5d5a26789752