一、所使用的数据表
1.dept表(部门表)说明:
deptno(部门号)、dname(部门名)、loc(地点)
+--------+------------+----------+
| DEPTNO | DNAME | LOC |
+--------+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+--------+------------+----------+
2.salgrade表(工资等级表)说明:
grade(工资等级)、losal(最低工资)、hisal(最高工资)
+-------+-------+-------+
| GRADE | LOSAL | HISAL |
+-------+-------+-------+
| 1 | 700 | 1200 |
| 2 | 1201 | 1400 |
| 3 | 1401 | 2000 |
| 4 | 2001 | 3000 |
| 5 | 3001 | 9999 |
+-------+-------+-------+
3.emp表(员工表)说明:
empno(员工编号)、ename(员工姓名)、job(工作)、mgr(上级领导编号)、hiredate(入职日期)、sal(月薪)、comm(津贴)、deptno(所在部门编号)
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
+-------+--------+-----------+------+------------+---------+---------+--------+
二、连接查询
连接查询:多张表联合起来查询数据。
连接查询的分类:
① 根据语法的年代分类:SQL92(1992年出现的语法,了解即可);SQL99(1999年出现的语法,重点学习)
② 根据表的连接方式分类:内连接(等值连接、非等值连接、自连接);外连接(左外连接、右外连接);全连接。
1.笛卡尔积:当两张表进行连接查询,没有任何条件限制的时候,最终查询结果条数是两张表条数的乘积。
(要避免笛卡尔积,连接次数越多,越影响查询效率)
//查询结果是笛卡尔积(14*4=56 rows in set (0.00 sec))
select ename,dname from emp,dept;
如何避免笛卡尔积:使用where条件对公共字段进行连接起来筛选。
//查询每个员工所在的部门名称,输出员工名和部门名。
//效率较低
select ename,dname from emp,dept where emp.deptno=dept.deptno;
//对表起别名,效率提高
select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;
三、内连接
内连接:结果集是两张表的公共部分,两张表没有主次关系。
SQL99语法:select 列名1,列名2 from 表a inner join 表b on a和b的连接条件 where 筛选条件;(inner可以省略)
SQL92语法:select 列名1,列名2 from 表a,表b where a和b的连接条件;
1.等值连接:连接条件是等量关系。如:e.deptno=d.deptno;
例:查询每个员工所在的部门名称,输出员工名和部门名。
//SQL92语法
select e.ename as '员工名',d.dname as '部门名' from emp e,dept d where e.deptno=d.deptno;
//SQL99语法
select e.ename as '员工名',d.dname as '部门名' from emp e join dept d on d.deptno=e.deptno;
2.非等值连接:连接条件不是等值关系。如:e.sal between s.losal and s.hisal;
例:查询每个员工的薪资等级,要求输出员工名、薪资、薪资等级。
select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;
3.自身连接(自连接):一张表通过起别名与自身连接。
例:查询员工对应的上级领导名,要求输出员工名对应的领导名。
select a.ename as '员工名',b.ename as '领导名' from emp a join emp b on a.mgr=b.empno;
四、外连接
1.右外连接(右连接):右外连接是以右边的表的数据为主,匹配左边表的数据。(左表不足时使用null补全)
语法格式:表a right outer join 表b
(outer可以省略)
例:查询员工所在的部门名,要求输出员工名对应的部门名。
select e.ename as '员工名',d.dname as '部门名' from emp e join dept d on d.deptno=e.deptno;//内连接
//右外连接
select e.ename as '员工名',d.dname as '部门名' from emp e right join dept d on d.deptno=e.deptno;
2.左外连接(左连接):左外连接是以左边的表的数据为主,匹配右边表的数据。(右表不足时使用null补全)
语法格式:表a left outer join 表b
(outer可以省略)
例:查询员工所在的部门名,要求输出员工名对应的部门名。
select e.ename as '员工名',d.dname as '部门名' from dept d left join emp e on e.deptno=d.deptno;
注意:
左连接和外连接可以互相转换。
外连接的查询结果集>=内连接的查询结果集。
例:查询每个员工的上级领导,要求输出员工名和领导名
//① 左外连接
select a.ename as '员工名',b.ename as '领导名' from emp a left join emp b on a.mgr=b.empno;
//② 右外连接
select a.ename as '员工名',b.ename as '领导名' from emp b right join emp a on a.mgr=b.empno;
思考:上面的左外连接和右外连接与下面的右外连接查询的结果集有什么区别?
select a.ename as '员工名',b.ename as '领导名' from emp a right outer join emp b on a.mgr=b.empno;
//此处的查询结果有21条
答:对于外连接的使用必须要注意前后的顺序。
若是左外连接,则是根绝左表的所查询的结果去顺带关联着查询右表的记录,结果条数由左表决定;
若是右外连接,则是根绝右表的所查询的结果去顺带关联着查询左表的记录,结果条数由右表决定。
3.全外连接(全连接):只要左表和右表其中一个表中存在匹配,则返回行,full outer join结合了 left outer join 和 right outer join的结果。(对于表a或表b中没有的数据使用null补全)
语法格式:表a full outer join 表b
(outer可以省略,对于全外连接了解即可,mysql自身不支持,也不常用)
mysql 不支持直接写full outer join 或者 full join来表示全外连接,但是可以用 左外连接 union 右外连接 代替。
//不支持全外连接
select e.*,d.* from emp as e full join dept as d on e.deptno=e.deptno;
替换为如下:
select * from emp left join dept on emp.deptno=emp.deptno union select * from emp right join dept on dept.deptno=emp.deptno;
4.多张表连接
语法格式:select 列名1,列名2... from a join b on a和b的连接条件 join c on a和c的连接条件 join d on a和d的连接条件...
(此处的连接可以是内连接也可以是外连接)
例1:查询每个员工的部门名称和工资等级,要求输出员工名、部门名、工资、工资等级。
select e.ename,e.sal,d.dname,s.grade from emp e join dept d on e.deptno=d.deptno join salgrade s on e.sal between losal and hisal;
例2:查询每个员工的部门名称和工资等级,要求输出员工名、上级领导名、部门名、工资、工资等级。
select e.ename as '员工名',l.ename as '领导名',e.sal,d.dname,s.grade from emp e join dept d on e.deptno=d.deptno join salgrade s on e.sal between losal and hisal left join emp l on e.mgr=l.empno;
连接查询总结:
A inner join B取交集。
A left join B取A全部,B没有对应的值为null。
A right join B取B全部,A没有对应的值为null。
A full outer join B取并集,彼此没有对应的值为null。
以上所有的连接条件在on后面填写。