概念:简单来说就是两个集合相乘的结果,集合A和集合B中任意两个元素结合在一起。
缺点:冗杂,得出来的结果并非是想要的,所以需要一种新的应用,将笛卡尔积出来的结果当成一个表格

/*笛卡尔积*/
SELECT * FROM course,teacher;
-- 给出条件,筛选得到我们所需要的有用的信息
SELECT * FROM course,teacher WHERE course.t_id = teacher.id;
-- 可以给表起别名,方便使用
SELECT * FROM course c,teacher t WHERE c.t_id = t.id;
内连接
内连接查询操作只列出与连接条件匹配的数据行,使用INNER JOIN或者直接使用JOIN 进行连接。
-- 第一种方式,join
select * from Table_A JOIN Table_B;
-- 第二种方式,inner join
select * from Table_A INNER JOIN Table_B;
内连接可以没有连接条件,没有条件之后的查询结果,会保留所有结果(笛卡尔集),与后面分享的交 叉连接差不多。
在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列, 包括其中的重复列。
-- 使用了join或者inner join 后面需要跟on进行连接
select * from Table_A AJOIN Table_B B ON A.id = B.id;
查询结果,注意列数是 4 列,两张表的字段直接拼接在一起,重复的字段在后面添加数字序列以做区分

通俗讲就是根据条件,找到表 A 和 表 B 的数据的交集

例子:
普通的多表查,课内连接接通相同
SELECT * from teacher t , course c where t.id = c.t_id   (这样会先生成笛卡尔积,效率可能略低)
SELECT * from teacher t JOIN course c on t.id = c.t_id 
SELECT * from teacher t inner JOIN course c on t.id = c.t_id 
结果:只有满足条件的会显示,5号老师没课程,5号课程没老师都不会显示 
1   王宝强 1   数学  1 
2   贾宝玉 2   语文  2 
3   温迪  3   c++ 3 
4   路人甲 4   java    4
外连接不只列出与连接条件相匹配的行,而且还加上左表(左外连接时)或右表(右外连接时)或两个表(全 外连接时)中所有符合搜索条件的数据行。
-- 第一种:left join
SELECT * FROM Table_A A LEFT JOIN Table_B B ON A.ID = B.ID
-- 第二种:left outer join
SELECT * FROM Table_A A LEFT OUTER JOIN Table_B B ON A.id = B.id;
查询结果:

根据条件,用右表(B)匹配左表(A),能匹配,正确保留,不能匹配其他表的字段都置空 Null。
也就是,根据条件找到表 A 和 表 B 的数据的交集,再加上左表的数据集, Venn 图表示就是

红色部分代表查询结果
例子:
SELECT * from teacher t LEFT JOIN course c on t.id = c.t_id 
结果:只有满足条件的会显示,5号老师没课程,依然显示,5号课程没老师都不会显示, 左边表的所有数据都显示
1   王宝强 1   数学  1 
2   贾宝玉 2   语文  2 
3   温迪  3   c++ 3 4   路人甲 
4   java    4 
5   路人乙        
-- 第一种:right join
SELECT * FROM Tabel_A RIGHT JOIN Table_B B ON A.id = B.id;
-- 第二种:right outer join
SELECT * FROM Table_A A RIGHT OUTER JOIN Table_B B ON A.id =B.id;
查询结果:

根据条件,用左表(A)匹配右表(B),能匹配,正确保留,不能匹配其他表的字段都置空 Null。 也就是,根据条件找到表 A 和 表 B 的数据的交集,再加上右表的数据集, Venn 图表示就是

例子:
SELECT * from teacher t right JOIN course c on t.id = c.t_id
结果:只有满足条件的会显示,5号老师没课程不显示,5号课程没老师都,依然显示, 右边表的所有数据都显示
1   王宝强  1   数学  1 
2   贾宝玉  2   语文  2 
3   温迪    3   c++ 3 
4   路人甲   4   java    4          
	 	    5    php 
SELECT * FROM Table_A A FULL JOIN Table_B B ON A.id = B.id;
SELECT * FROM Table_A A FULL OUTER JOIN Table_B B ON A.id = B.id;
目前我的 MySQL 不支持此种方式,可以用其他方式替代解决,在此不展开。
理论上是根据条件找到表 A 和 表 B 的数据的交集,再加上左右表的数据集

将查询结果当条件
例子:查询有一门学科分数大于八十分的学生信息
SELECT * from student where id in (select DISTINCT s_id from scores where score > 90);
-- 等于号的使用
SELECT * FROM student WHERE id = 
(SELECT s_id FROM scores GROUP BY s_id ORDER BY SUM(score) DESC LIMIT 1);
where 型子查询,如果是 where 列 =(内层 sql) 则内层 sql 返回的必须是单行单列,单个值。
where 型子查询,如果是 where 列 in(内层 sql) 则内层 sql 返回的必须是单列,可以多行。
在学习 from 子查询之前,需要理解一个概念:查询结果集在结构上可以当成表看,那就可以当成临时 表对他进行再次查询:
取排名数学成绩前五名的学生,正序排列。
-- FROM
-- 取排名数学成绩前五名学生,正序排列
SELECT * FROM student s left JOIN scores e on s.id = e.s_id 
LEFT JOIN course c ON e.c_id = c.id WHERE c.`NAME` = ‘数学‘ 
ORDER BY e.score DESC LIMIT 5;
-- 正序排列
SELECT * FROM (SELECT s.id id,s.name name,e.score score,c.name cname FROM student s LEFT JOIN scores e
ON s.id = e.s_id LEFT JOIN course c ON e.c_id = c.id 
WHERE c.`NAME` = ‘数学‘ ORDER BY e.score DESC LIMIT 5 ) t ORDER BY t.score;
1、查询‘01’号学生的姓名和各科成绩。 *
-- 1、查询‘01’号学生的姓名和各科成绩
SELECT s.name,e.score,c.`NAME` FROM 
student s  LEFT JOIN scores e  on s.id = e.s_id
LEFT JOIN course c on e.c_id = c.id WHERE s.id = ‘1‘;
2、查询各个学科的平均成绩,高成绩。 *
-- 2、查询各个学科的平均成绩,高成绩。
SELECT c.`NAME`,avg(score) ‘平均成绩‘,MAX(score) ‘最高成绩‘
FROM scores s INNER JOIN course c ON c.id = s.c_id
GROUP BY c.`NAME`;
3、查询每个同学的高成绩及科目名称。 *
-- 3、查询每个同学的高成绩及科目名称。
-- 思路:先拿到每个id的最大成绩
SELECT st.id,st.`NAME`,c.`NAME` ‘课程名‘,sc.score ‘最高成绩‘ 
FROM student st LEFT JOIN scores sc on st.id = sc.s_id
LEFT JOIN course c ON sc.c_id = c.id
WHERE sc.score in(
SELECT max(sc.score) FROM scores sc GROUP BY sc.s_id)
4、查询所有姓张的同学的各科成绩。 *
-- 4、查询所有姓张的同学的各科成绩。
SELECT student.id,student.`NAME`,course.`NAME`,scores.score FROM 
student  LEFT JOIN scores ON student.id = scores.s_id  
LEFT JOIN course  on scores.c_id = course.id 
WHERE student.`NAME` LIKE ‘张%‘;
5、查询每个课程高分的同学信息。 *
-- 5、查询每个课程高分的同学信息。
SELECT
	s_id,
	st.age,
	st.gander,
	st. NAME NAME,
	c. NAME project,
	temp.score
FROM
	scores s
INNER JOIN (
	SELECT
		c_id,
		max(score) score
	FROM
		scores
	GROUP BY
		c_id
) temp ON s.c_id = temp.c_id
AND s.score = temp.score
LEFT JOIN student st ON s.s_id = st.id
LEFT JOIN course c ON c.id = temp.c_id;
6、查询名字中含有“张”和‘李’字的学生信息和各科成绩 *
-- 6、查询名字中含有“张”和‘李’字的学生信息和各科成绩
SELECT s.id ‘学号‘,s.name ‘姓名‘,s.age ‘年龄‘,s.gander ‘性别‘,c.`NAME` ‘科目‘,e.score ‘成绩‘
FROM student s LEFT JOIN scores e ON s.id = e.s_id
LEFT JOIN course c on e.c_id = c.id WHERE s.`NAME` LIKE ‘张%‘
7、查询平均成绩及格的同学的信息。*
/*平均成绩
SELECT AVG(score) FROM scores WHERE scores.s_id = ‘7‘;*/
SELECT s.id,s.`NAME`,s.age,s.gander,ROUND(AVG(e.score),2)score
FROM student s LEFT JOIN scores e on s.id = e.s_id GROUP BY s.id
HAVING AVG(e.score )>60
8、将学生按照总分数进行排名。 *
9、查询数学成绩的高分、低分、平均分。
10、将各科目按照平均分排序。 **
11、查询老师的信息和他所带科目的平均分。 **
12、查询被“张楠”和‘‘老孙’叫的课程的高分和平均分。 **
13、查询查询每个同学的好成绩的科目名称。 **
14、查询所有学生的课程及分数。**
15、查询课程编号为01且课程成绩在80分以上的学生的学号和姓名。** 16、查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩。 ** 17、查询有不及格课程的同学信息。 **
18、求每门课程的学生人数。 **
19、查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列 。 ** *
20、查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩。 * **
21、查询有一门课程成绩在90分以上的学生信息; *** ****
22、查询出只有三门课程的全部学生的学号和姓名 ** *
23、查询有不及格课程的课程信息 ** *
24、检索至少选修四门课程的学生学号 * **
25、查询没有学全所有课程的同学的信息 * **
26、查询学全所有课程的同学的信息。 *** *
27、 查询各学生都选了多少门课 ** *
28、查询课程名称为”数学”,且分数低于60的学生姓名和数学分数。 ***
29、查询学过”张楠”老师授课的同学的信息 。*** *
30、查询没学过”张楠”老师授课的同学的信息 * ***
-- 8、将学生按照总分数进行排名。
SELECT s.id,s.`NAME`,SUM(e.score) 
FROM student s LEFT JOIN scores e on s.id = e.s_id GROUP BY s.id
ORDER BY sum(e.score)DESC
-- 9、查询数学成绩的高分、低分、平均分。 
SELECT MAX(score) ‘数学最高分‘,MIN(score) ‘最低分‘,avg(score) ‘平均分‘
FROM scores e LEFT JOIN course c ON e.c_id = c.id WHERE c.NAME = ‘数学‘;
-- 10、将各科目按照平均分排序。
SELECT avg(score),c.`NAME`
FROM scores e LEFT JOIN course c ON e.c_id = c.id 
GROUP BY c.id ORDER BY avg(score) DESC;
-- 11、查询老师的信息和他所带科目的平均分
SELECT t.id,t.`NAME`,c.`NAME`,AVG(score) score 
FROM teacher t LEFT JOIN course c on t.id = c.t_id
LEFT JOIN scores s ON c.id = s.c_id
GROUP BY t.id,t.`NAME`
ORDER BY score ASC;
-- 12、查询被“张楠”和‘‘老孙’教的课程的高分和平均分。
SELECT t.`NAME` teacher,c.`NAME` project,avg(s.score) ‘平均分‘,MAX(s.score) ‘最高分‘ 
FROM course c LEFT JOIN scores s on c.t_id = s.c_id
LEFT JOIN teacher t ON s.c_id = t.id
WHERE t.`NAME` = ‘张楠‘ OR t.`NAME` =‘老孙‘
GROUP BY c.`NAME`,t.`NAME`;
-- 13、查询每个同学的最好成绩的科目名称
SELECT st.`NAME`,c.`NAME` ‘科目‘,temp.`最高成绩` 
FROM student st LEFT JOIN(
SELECT sc.s_id,MAX(sc.score) ‘最高成绩‘ 
FROM scores sc GROUP BY s_id) temp ON st.id = temp.s_id
LEFT JOIN scores s ON s.score = temp.`最高成绩`
AND s.s_id = temp.s_id
LEFT JOIN course c ON c.id = s.c_id;
-- 14、查询所有学生的课程及分数。** 
SELECT s.name,e.score,c.`NAME` FROM 
student s  LEFT JOIN scores e  on s.id = e.s_id
LEFT JOIN course c on e.c_id = c.id;
-- 15、查询课程编号为01且课程成绩在80分以上的学生的学号和姓名
SELECT sc.s_id,st.`NAME`,sc.score
FROM student st LEFT JOIN scores sc ON st.id = sc.s_id
LEFT JOIN course c ON sc.s_id = c.id
WHERE c.id = 1 
AND score >= 75;
-- 16、查询平均成绩大于等于70的所有学生的学号、姓名和平均成绩
SELECT st.id ‘学号‘,st.`NAME` ‘姓名‘,avg(sc.score) ‘平均成绩‘
FROM student st LEFT JOIN scores sc ON st.id = sc.s_id
GROUP BY s_id
HAVING avg(sc.score) >= 70;
-- 17、查询有不及格课程的同学信息 
SELECT st.id,st.`NAME`,c.`NAME`,sc.score 
FROM student st LEFT JOIN scores sc ON st.id = sc.s_id
LEFT JOIN course c ON sc.c_id = c.id
WHERE sc.score < 60;
-- 18、求每门课程的学生人数 
SELECT sc.c_id,c.`NAME`,COUNT(sc.s_id) ‘人数‘ 
FROM scores sc LEFT JOIN course c ON sc.c_id = c.id
GROUP BY sc.c_id,c.`NAME`
-- 19、查询每门课程的平均成绩,结果按平均成绩降序排列,
-- 平均成绩相同时,按课程编号升序排列 
SELECT sc.c_id,c.`NAME`,avg(sc.score) ‘平均成绩‘  
FROM scores sc LEFT JOIN course c ON sc.c_id = c.id
GROUP BY sc.c_id,c.`NAME` 
ORDER BY avg(sc.score) DESC,
sc.c_id ASC;
-- 20、查询平均成绩大于等于70分的同学的学生编号和学生姓名和平均 成绩。 
SELECT st.id,st.`NAME`,avg(sc.score) ‘平均成绩‘ 
FROM student st LEFT JOIN scores sc ON st.id = sc.s_id
GROUP BY sc.s_id
HAVING avg(sc.score) >= 70;
-- 21、查询有一门课程成绩在90分以上的学生信息
SELECT st.id,st.`NAME`,st.age,st.gander,c.`NAME` ‘科目‘,sc.score 
FROM student st LEFT JOIN scores sc ON st.id = sc.s_id
LEFT JOIN course c ON sc.c_id = c.id
WHERE score > 90;
-- 22、查询出只有三门课程的全部学生的学号和姓名 
SELECT st.id,st.`NAME` 
FROM student st LEFT JOIN scores sc ON st.id = sc.s_id
LEFT JOIN course c ON c.id = sc.c_id
GROUP BY st.id,st.`NAME`
HAVING COUNT(sc.c_id) = 3;
-- 23、查询有不及格课程的详细信息
SELECT sc.c_id ‘课程编号‘,sc.c_id ‘学号‘, st.`NAME` ‘姓名‘,c.`NAME` ‘科目‘,
sc.score ‘成绩‘,t.`NAME` ‘教师‘
FROM scores sc LEFT JOIN course c ON sc.c_id = c.id
LEFT JOIN student st ON st.id = sc.s_id
LEFT JOIN teacher t ON c.t_id = t.id
WHERE sc.score < 60;
-- 24、检索至少选修四门课程的学生学号 
SELECT st.id ‘学号‘,st.`NAME` ‘姓名‘  
FROM student st LEFT JOIN scores sc ON st.id = sc.s_id
GROUP BY st.id,st.`NAME`
HAVING COUNT(sc.c_id) >= 4;
-- 25、查询没有学全所有课程的同学的信息
SELECT * 
FROM student st LEFT JOIN( 
SELECT * FROM scores sc GROUP BY s_id 
HAVING COUNT(c_id) < (SELECT COUNT(*) FROM course))t 
ON st.id = t.s_id
-- 26、查询学全所有课程的同学的信息 
SELECT * 
FROM student s INNER  JOIN (
SELECT s_id FROM scores GROUP BY s_id 
HAVING count( c_id )=( SELECT count(*) FROM course ) ) t   
ON s.id = t.s_id;
-- 27、 查询各学生都选了多少门课 
SELECT st.id,st.`NAME`,COUNT(sc.c_id) ‘数量‘ 
FROM student st LEFT JOIN scores sc ON st.id = sc.s_id
GROUP BY st.id,st.`NAME`;
-- 28、查询课程名称为”数学”,且分数低于60的学生姓名和数学分数
SELECT st.`NAME`,sc.score ‘成绩‘ 
FROM student st LEFT JOIN scores sc ON st.id = sc.s_id
LEFT JOIN course c ON sc.c_id = c.id
WHERE c.`NAME` = ‘数学‘ AND score < 60;
-- 29、查询学过”张楠”老师授课的同学的信息
SELECT st.id,st.`NAME`,st.gander,st.age,t.`NAME`,c.`NAME` 
FROM course c LEFT JOIN teacher t ON c.t_id = t.id
LEFT JOIN scores sc ON c.id = sc.c_id
LEFT JOIN student st ON sc.s_id = st.id
WHERE t.`NAME` = ‘张楠‘;
-- 30、查询没学过”张楠”老师授课的同学的信息 
SELECT *
FROM student
WHERE id NOT in(
SELECT sc.s_id
FROM course c LEFT JOIN scores sc ON c.id = sc.c_id
LEFT JOIN teacher t ON c.t_id = t.id
WHERE t.`NAME` = ‘张楠‘);
数据库多表查询,请先把我文章的基础知识学会,在钻研难点!!!
原文:https://www.cnblogs.com/wusanshui-a/p/13093397.html