一、多表查询
显示雇员名、雇员工资以及所在部门的名字:

为了得出结果,我们必须让这两张表合并成一张表:

得到的一张非常大的表,这个表是由 emp 表的第一行和 dept 表的第一行、第二行等进行组合而来,以此类推,emp 表的第二行和 dept 的表的第一行、第二行等进行组合等等,最终得到这张表;这个结果称为笛卡尔积;
为了让员工的 emp 的部门编号和 dept 的部门编号进行适配,最终达成部门一致:

最后:显示员工名字、工资、部门:

显示部门号为10的部门名,员工名和工资:

显示各个员工的姓名,工资,及工资级别:

二、自连接
对同一张表进行笛卡尔积的操作称为自连接:

显示员工FORD的上级领导的编号和姓名(mgr是员工领导的编号--empno):
1)使用子查询:

2)自连接:

三、单行子查询
显示SMITH同一部门的员工:

三、多行子查询
查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10自己:

显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号:

显示工资比部门30的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门的员工):

四、多列子查询
查询和SMITH的部门和岗位完全相同的所有雇员,不含SMITH本人:

mysql> select * from emp where (deptno,job) = (select deptno,job from emp where ename='SMITH');
+--------+-------+-------+------+---------------------+---------+------+--------+
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+--------+-------+-------+------+---------------------+---------+------+--------+
| 007369 | SMITH | CLERK | 7902 | 1980-12-17 00:00:00 | 800.00 | NULL | 20 |
| 007876 | ADAMS | CLERK | 7788 | 1987-05-23 00:00:00 | 1100.00 | NULL | 20 |
+--------+-------+-------+------+---------------------+---------+------+--------+
2 rows in set (0.00 sec)
mysql> select * from emp where (deptno,job) = (select deptno,job from emp where ename='SMITH') and ename != 'SMITH';
+--------+-------+-------+------+---------------------+---------+------+--------+
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+--------+-------+-------+------+---------------------+---------+------+--------+
| 007876 | ADAMS | CLERK | 7788 | 1987-05-23 00:00:00 | 1100.00 | NULL | 20 |
+--------+-------+-------+------+---------------------+---------+------+--------+
1 row in set (0.00 sec)
mysql> select * from emp where (deptno,job) in (select deptno,job from emp where ename='SMITH') and ename != 'SMITH';
+--------+-------+-------+------+---------------------+---------+------+--------+
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+--------+-------+-------+------+---------------------+---------+------+--------+
| 007876 | ADAMS | CLERK | 7788 | 1987-05-23 00:00:00 | 1100.00 | NULL | 20 |
+--------+-------+-------+------+---------------------+---------+------+--------+
1 row in set (0.01 sec)
五、在 from 子句中使用子查询
之前我们都是在 where 右侧使用子查询,现在我们来使用在 from 中使用子查询:
显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资:

mysql> select * from emp,(select deptno,avg(sal) myavg from emp group by deptno) tmp where emp.deptno=tmp.deptno and emp.sal>tmp.myavg;
·查找每个部门工资最高的人的姓名、工资、部门、最高工资:
mysql> select ename,sal,t1.deptno,mymax from emp t1,(select deptno,max(sal) mymax from emp group by deptno) t2 where t1.deptno=t2.deptno and t1.sal=t2.mymax;

显示每个部门的信息(部门名,编号,地址)和人员数量:
mysql> select t1.dname,t1.loc,t2.dept_num,t1.deptno from dept t1,(select deptno,count(*) dept_num from emp group by deptno) t2 where t1.deptno=t2.deptno;

解决多表问题的本质:想办法将多表转换成单表,所以在 MySQL 中,所有的 select 的问题全部都可以转成单表问题;
六、合并查询
在实际应用中,为了合并多个select的执行结果,可以使用集合操作符union,union all;
union:该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。
将工资大于2500或职位是MANAGER的人找出来:

union all:该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。

七、内连接

八、外连接
1)左外连接

查询所有学生的成绩,如果这个学生没有成绩,也要将学生的个人信息显示出来:

2)右外连接

