多表查询

有两张表
课程表和老师表。
两个表之间的关系,是通过tid关联在一起
基本语法
select 字段名 from table1,table2where 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,scWHERE scholar.Sid=sc.SidGROUP BY sc.SidORDER 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);```sqlselect scholar.sid,sname,cname,score from scholar,sc,coursewhere sc.sid = scholar.sid and sc.cid = course.cid;

汇总每门课程课程名,总成绩,平均成绩,考试人数
select cname, sum(score), avg(score), count(1) from scholar,sc,coursewhere sc.sid = scholar.sid and sc.cid = course.cidGROUP BY cname;
总结
在做多表查询的时候:
找到每个表之间对应的关系。关系写在 where 子句中。
- 后面的操作跟单表操作原理一样。
内联接 inner join


inner join 在连接多个表的时候主要过滤出来表中共同的数据。
使用 inner join 查询 学生姓名(sname),学生成绩(score);
select sname,score from scholarinner join sc -- 连接表on sc.sid = scholar.sid; -- 表之间的关联
使用 inner join 内连接 与上面使用 where 多表查询 效果一样。
查询学生姓名(sname),考试科目(cname),成绩(score);

select sname,cname,score from scholarinner join scon scholar.sid = sc.sidinner join courseon sc.cid = course.cid;

- 学生姓名(sname),考试科目(cname),对应老师姓名(tname),成绩(score);
SELECT sname, cname,tname,score from scholarINNER JOIN scON sc.Sid = scholar.SidINNER JOIN courseON course.cid = sc.cidINNER JOIN teacherON teacher.Tid = course.Tid;

左联结 left join

- 查询学生姓名,学生的成绩(如果学生没有对应的成绩,显示为Null)

select sname,score from scholarleft join scon scholar.sid = sc.sid;

- 查询张三同学的所有的考试科目(cname),成绩(score);
SELECT "张三" AS 姓名, cname 课程 ,score 成绩 from courseLEFT JOIN (SELECT * from sc WHERE sid in (SELECT sid from scholar WHERE sname="张三" )) as stu1ON 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```sqlSELECT course,sum(score) from studentsWHERE 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.查询姓"张"的学生名单;```sqlselect * from scholarwhere sname like "张%";
2.查询平均成绩大于60分的同学的学号和平均成绩;
select sid, avg(score) from scgroup by sidhaving avg(score) > 60;
3.查询所有同学的学号、姓名、选课数、总成绩;
select scholar.sid,sname,count(course.cid),sum(score) from scholarinner join scon scholar.sid = sc.sidinner join courseon course.cid = sc.cidGROUP BY scholar.Sid,Sname
4.查询没学过王大锤老师课的同学的学号、姓名;
-- 1. 找到王大锤老师的 课程id cidselect cid from courseinner join teacheron course.tid = teacher.tidwhere tname = "王大锤"-- 2. 从成绩表中找到没有 王大锤的 cid的学号 sidselect DISTINCT(sid) from scwhere cid <> (select cid from courseinner join teacheron course.tid = teacher.tidwhere tname = "王大锤")-- 根据学号 可以找到姓名SELECT sid,sname from scholarWHERE sid in (select DISTINCT(sid) from scwhere cid <> (select cid from courseinner join teacheron course.tid = teacher.tidwhere tname = "王大锤"));
5.查询每门课程被选修的学生数;
select cid, count(cid) from scgroup by cid;-- 也可以select (select course.Cname from course WHERE course.Cid =sc.Cid) as 科目, count(cid) 选修人数 from scgroup by cid;
7.查询学生名单,统计男生,女生人数;
select ssex,count(ssex) from scholargroup by ssex;
8.查询出只修了一门课程的全部学生的学号和姓名;
-- 1. 查找修一门课的学号 sidSELECT sid from scGROUP BY sidHAVING count(sid) = 1-- 2. 根据学号 找人select sid,sname from scholarWHERE sid in (SELECT sid from scGROUP BY sidHAVING count(sid) = 1)
9.统计每个同学的课程成绩,并按课程号从大到小排序列;
select sname,cname, score from scholarinner join scon sc.sid = scholar.sidinner join courseon course.cid = sc.cidorder by course.cid
10.语文成绩大于数学成绩的学生信息;
select scholar.sid 学号,sname 名字 from scholarINNER JOIN scON sc.sid = scholar.SidINNER JOIN courseON sc.cid = course.Cid-- 语文成绩 并且语文大于数学WHERE cname = "语文" AND score > (-- 查询数学成绩SELECT 数学 from (select scholar.sid 学号,sname 名字,score 数学 from scholarINNER JOIN scON sc.sid = scholar.SidINNER JOIN courseON sc.cid = course.CidWHERE cname = "数学") as mathWHERE 学号 = math.学号);

1.查出平均成绩>85的学生学号,姓名,平均成绩;
select No,Name,avg(score) from studentsgroup by No,Namehaving avg(score) > 85;
2.在students表中 查询出每门课都大于80分的学生姓名;
-- 都大于80, 最低分大于80 即可select no, name from studentsgroup by no,namehaving min(score) > 80;
3.查出平均成绩第一名的学生;
-- 最高的平均成绩select avg(score) from studentsgroup by Noorder by avg(score) desclimit 1-- 根据成绩找人select No,Name,avg(score) from studentsgroup by No,Namehaving avg(score) = (select avg(score) from studentsgroup by Noorder by avg(score) desclimit 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 studentsGROUP 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 studentsGROUP BY No,Name) as tmpwhere 语文>数学;
附件
https://pear-fall-0cf.notion.site/64874dc67957406ca99d5d5a26789752
