连接查询
-
什么是连接查询?
- 查询的时候只从一张表检索数据,被称为单表查询
- 在实际的开发中,数据并不是存储在一张表中的,是同时存储在多张表中,这些表和表之前存在关系,在检索的时候通常是需要将多张表联合起来取得有效数据,这种多表查询被称为连接查询或者叫做跨表查询. -
连接查询根据出现的年代分类:
- SQL92(1992)
- SQL99(1999:更新的语法,主要掌握这种语法) -
连接查询根据连接方式可以分为:
- 内连接
- 等值连接
- 非等值连接
- 自连接
- 外链接
- 左外连接(左连接)
- 右外连接(有连接)
-
当多张表进行连接查询,若没有任何条件进行限制,会发生什么现象?
- 案例:查询每一个员工所在的部门名称,最终要求显示员工名和对应的部门名.
mysql> select ename,deptno from emp; emp是员工表
+--------+--------+
| ename | deptno |
+--------+--------+
| SIMITH | 20 |
| ALLEN | 30 |
| WARD | 30 |
| JONES | 20 |
| MARTIN | 30 |
| BLAKE | 30 |
| CLARK | 10 |
| SCOTT | 20 |
| KING | 10 |
| TURNER | 30 |
| ADAMS | 20 |
| JAMES | 30 |
| FORD | 20 |
| MILLER | 10 |
+--------+--------+
14 rows in set (0.00 sec)
mysql> select deptno,dname from dept; dept是部门表
+--------+-------------+
| deptno | dname |
+--------+-------------+
| 10 | ACCOUNTING |
| 20 | RESEARCHING |
| 30 | SALES |
| 40 | OPERATIONS |
+--------+-------------+
4 rows in set (0.00 sec)
- 主要分析: 多张表连接查询,若没有任何条件限制,会发生什么?
- 小知识点: 在进行多表连接查询的时候,尽量给表起别名,这样效率高,可读性好.
select e.ename,d.dname from emp e,dept d;
//笛卡尔乘积
+--------+-------------+
| ename | dname |
+--------+-------------+
| SIMITH | ACCOUNTING |
| SIMITH | RESEARCHING |
| SIMITH | SALES |
| SIMITH | OPERATIONS |
| ALLEN | ACCOUNTING |
| ALLEN | RESEARCHING |
| ALLEN | SALES |
| ALLEN | OPERATIONS |
...........................................
+--------+-------------+
56 rows in set (0.00 sec)
-
结论: 若两张表进行连接查询的时候没有任何条件限制,最终的查询结果总数是两张表记录条数的笛卡尔乘积.
-
查询每一个员工所在的部门名称,最终要求显示员工名和对应的部门名.(内连接中的等值连接)
//SQL92语法: 内连接中的等值连接
select emp.ename,dept.dname from emp,dept where emp.deptno = dept.deptno;
//SQL99语法: 内连接中的等值连接
select emp.ename,dept.dname from emp join dept on emp.deptno = dept.deptno;
+--------+-------------+
| ename | dname |
+--------+-------------+
| CLARK | ACCOUNTING |
| KING | ACCOUNTING |
| MILLER | ACCOUNTING |
| SIMITH | RESEARCHING |
| JONES | RESEARCHING |
| SCOTT | RESEARCHING |
| ADAMS | RESEARCHING |
| FORD | RESEARCHING |
| ALLEN | SALES |
| WARD | SALES |
| MARTIN | SALES |
| BLAKE | SALES |
| TURNER | SALES |
| JAMES | SALES |
+--------+-------------+
14 rows in set (0.04 sec)
- 注意: 在连接查询的时候虽然使用了限制条件,但是匹配的次数没有减少,只不过这一次的结果都是有效记录.
- SQL99语法的优点 : 表连接独立出来了,结构更清晰,对表连接不满意的话,后面追加where.
-找出每个员工对应的工资等级,要求显示员工名,工资,工资等级.(内连接中的非等值连接)
mysql> select ename,sal,grade from emp join salgrade on sal >= losal and sal <= hisal;
+--------+---------+-------+
| ename | sal | grade |
+--------+---------+-------+
| SIMITH | 800.00 | 1 |
| ALLEN | 1600.00 | 3 |
| WARD | 1250.00 | 2 |
| JONES | 2975.00 | 4 |
| MARTIN | 1250.00 | 2 |
| BLAKE | 2850.00 | 4 |
| CLARK | 2450.00 | 4 |
| SCOTT | 3000.00 | 4 |
| KING | 5000.00 | 5 |
| TURNER | 1500.00 | 3 |
| ADAMS | 1100.00 | 1 |
| JAMES | 950.00 | 1 |
| FORD | 3000.00 | 4 |
| MILLER | 1300.00 | 2 |
+--------+---------+-------+
14 rows in set (0.00 sec)
- 案例:找出每个员工的上级领导,要求显示员工名以及对应的领导名(内连接中的自连接)
mysql> select a.ename empname ,b.ename leadername from emp a join emp b on a.mgr = b.empno;
+---------+------------+
| empname | leadername |
+---------+------------+
| SIMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
+---------+------------+
13 rows in set (0.00 sec)
-
案例 : 找出每一个员工对应的部门名称,要求部门名称全部显示.
-
内连接:
- A表和B表能够完全匹配的记录查询出来,被称为内连接 -
外链接:
- A表和B表能够完全匹配的记录查询出来之外,将其中一张表的记录无条件的完全查询出来,对方表没有匹配的记录,会用NULL与之匹配,这种查询被称为外链接.
//右连接
mysql> select e.ename ,d.dname from emp e right join dept d on e.deptno = d.deptno;
//左连接
mysql> select e.ename ,d.dname from dept d left join emp e on e.deptno = d.deptno;
+--------+-------------+
| ename | dname |
+--------+-------------+
| CLARK | ACCOUNTING |
| KING | ACCOUNTING |
| MILLER | ACCOUNTING |
| SIMITH | RESEARCHING |
| JONES | RESEARCHING |
| SCOTT | RESEARCHING |
| ADAMS | RESEARCHING |
| FORD | RESEARCHING |
| ALLEN | SALES |
| WARD | SALES |
| MARTIN | SALES |
| BLAKE | SALES |
| TURNER | SALES |
| JAMES | SALES |
| NULL | OPERATIONS |
+--------+-------------+
15 rows in set (0.00 sec)
-
注意 : 任何一个右外连接都可以写成左外连接,任何一个左外连接也同样可以写成右外连接
-
案例 : 找出每一个员工对应的领导名,要求显示所有的员工.
mysql> select a.ename empname ,b.ename leadername from emp a left join emp b on a.mgr = b.empno;
+---------+------------+
| empname | leadername |
+---------+------------+
| SIMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| KING | NULL |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
+---------+------------+
14 rows in set (0.00 sec)
- 案例 : 找出每一个员工对应的部门名称,以及该员工对应的工资等级.要求显示员工名,部门名,工资等级.
mysql> select emp.ename empname,dept.dname deptname,salgrade.grade grade from emp join dept on emp.deptno = dept.deptno join salgrade on sal >= losal and sal <= hisal;
+---------+-------------+-------+
| empname | deptname | grade |
+---------+-------------+-------+
| SIMITH | RESEARCHING | 1 |
| ALLEN | SALES | 3 |
| WARD | SALES | 2 |
| JONES | RESEARCHING | 4 |
| MARTIN | SALES | 2 |
| BLAKE | SALES | 4 |
| CLARK | ACCOUNTING | 4 |
| SCOTT | RESEARCHING | 4 |
| KING | ACCOUNTING | 5 |
| TURNER | SALES | 3 |
| ADAMS | RESEARCHING | 1 |
| JAMES | SALES | 1 |
| FORD | RESEARCHING | 4 |
| MILLER | ACCOUNTING | 2 |
+---------+-------------+-------+
14 rows in set (0.00 sec)
- 多张表进行表连接的语法格式:
select xxx from a join b on 条件 join c on 条件;
- 注意 : a表先和b表连接,然后a表再和c表连接.