- INNER JOIN:如果表中有至少一个匹配,则返回行。例如返回有学号且参加了考试的学生信息+分数表;
- LEFT JOIN:即使右表中没有匹配,也从左表返回所有的行。例如返回全部学生的成绩,不管是否参加考试;
- RIGHT JOIN:即使左表中没有匹配,也从右表返回所有的行。比如返回全部的成绩信息,不管成绩是否挂钩了学生的学号;
- FULL JOIN:只要其中一个表中存在匹配,则返回行。比如返回全部学生和成绩,不管学生是否参加考试,也不管成绩是否挂钩学生的学号。
一、下面是例子(有如下4张表):
1、学生表 Student(SId,Sname,Sage,Ssex) SId 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别
2、课程表 Course(CId,Cname,TId) CId 课程编号,Cname 课程名称,TId 教师编号
3、教师表 Teacher(TId,Tname) TId 教师编号,Tname 教师姓名
4、成绩表 SC(SId,CId,score) SId 学生编号,CId 课程编号,score 分数
二、写出以下SQL:
1、查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数
2、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )
3、查询学过「张三」老师授课的同学的信息
4、查询没有学全所有课程的同学的信息
5、查询每门功成绩最好的前两名
三、SQL解答:
1、查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数
SELECT s.*, a.cid, a.score, b.cid, b.score
FROM student s JOIN sc a ON s.sid = a.sid and a.cid = '01'
JOIN sc b ON s.sid = b.sid and b.cid = '02'
WHERE a.score > b.score;
2、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )
SELECT s.sid, s.sname, count(sc.cid), sum(sc.score)
FROM student s LEFT JOIN sc ON s.sid = sc.sid
GROUP BY s.sid, s.sname;
3、查询学过「张三」老师授课的同学的信息
SELECT s.*
FROM student s JOIN sc ON s.sid = sc.sid
JOIN course c ON sc.cid = c.cid
JOIN teacher t ON c.tid = t.tid
WHERE t.tname = '张三';
4、查询没有学全所有课程的同学的信息
SELECT s.*
FROM student s LEFT JOIN sc ON s.sid = sc.sid
LEFT JOIN course c ON sc.cid = c.cid
GROUP BY s.sid
HAVING COUNT(s.sid) < (SELECT count(*) FROM course);
5、查询每门功成绩最好的前两名
SELECT a.*
FROM sc a LEFT JOIN sc b ON a.cid = b.cid and a.score < b.score
GROUP BY a.sid, a.cid
HAVING count(b.score)+1 < 3
ORDER BY a.cid, a.sid;
PS:其他SQL见连接:https://www.cnblogs.com/greatLong/p/11466853.html
四、编写SQL查询语句的技巧
- 明确你要查询的数据(精确到列) 提示:先把所有的形容词去掉
- 确定这些列来自哪些表 提示:把形容词一个一个的加入进去
- 根据表的数量,来确定使用单表查询还是多表查询(联合查询,子查询,连接查询)
- 99%的情况下,只要看到“每”字,就一定要想到分组(GROUP BY)分组的依据是“每”字后面的词(having)