【MySQL】十五、内连接(等值连接,非等值连接,自连接)

文章目录

1. 内连接

内连接最大的特点是:条件是等量关系。

案例:查询每个员工的部门名称,要求显示员工名和部门名。

从emp表中取ename,从dept表中取dname

SQL92(太老了,不用):

select e.ename,d.dname from emp e, dept d where d.deptno = e.deptno;  

SQL99(常用):

select e.name, d.dname from emp e join dept d on d.deptno = e.deptno;

SQL99语法:

select 
	...
 from
	表 A
inner join // inner可以省略 ,带inner可读行更好
	表B
on 
	连接条件
where
	...

SQL99语法优于SQL92,因为SQL99进行where过滤的条件与on进行等值连接的条件分离了,语法结构更清晰。

2. 非等值连接

最大特点是:连接条件中的关系是非等量关系;

案例:找出每个员工的工资等级,要求显示员工名、工资、工资等级。

(1)首先,emp 表中记录了员工名(ename),工资(sal);

select ename, sal from emp;
+--------+---------+
| ename  | sal     |
+--------+---------+
| SMITH  |  800.00 |
| ALLEN  | 1600.00 |
| WARD   | 1250.00 |
| JONES  | 2975.00 |
| MARTIN | 1250.00 |
| BLAKE  | 2850.00 |
| CLARK  | 2450.00 |
| SCOTT  | 3000.00 |
| KING   | 5000.00 |
| TURNER | 1500.00 |
| ADAMS  | 1100.00 |
| JAMES  |  950.00 |
| FORD   | 3000.00 |
| MILLER | 1300.00 |
+--------+---------+
14 rows in set (0.00 sec

(2)salgrade表中记录了grade(工资等级)等。

select grade,sal from salgrade;
+-------+-------+-------+
| GRADE | LOSAL | HISAL |
+-------+-------+-------+
|     1 |   700 |  1200 |
|     2 |  1201 |  1400 |
|     3 |  1401 |  2000 |
|     4 |  2001 |  3000 |
|     5 |  3001 |  9999 |
+-------+-------+-------+
5 rows in set (0.00 sec)

因此,上案例的sql语句可以成:

select e.ename, e.sal, s.grade 
from emp e 
inner join salgrade s  // inner 可以省略
on e.sal between s.losal and s.hisal;
+--------+---------+-------+
| ename  | sal     | grade |
+--------+---------+-------+
| SMITH  |  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 |
+--------+---------+-------+

3. 自连接

最大特点:一张表看做两张表,自己连自己。

案例: 找出每个员工的上级领导,要求显示员工名和对应的领导名。

select empno, ename, mgr from emp;
+-------+--------+------+
| empno | ename  | mgr  |  # mgr 为上级领导编号
+-------+--------+------+
|  7369 | SMITH  | 7902 |
|  7499 | ALLEN  | 7698 |
|  7521 | WARD   | 7698 |
|  7566 | JONES  | 7839 |
|  7654 | MARTIN | 7698 |
|  7698 | BLAKE  | 7839 |
|  7782 | CLARK  | 7839 |
|  7788 | SCOTT  | 7566 |
|  7839 | KING   | NULL |
|  7844 | TURNER | 7698 |
|  7876 | ADAMS  | 7788 |
|  7900 | JAMES  | 7698 |
|  7902 | FORD   | 7566 |
|  7934 | MILLER | 7782 |
+-------+--------+------+
14 rows in set (0.00 sec)

思路:

(1)我们发现,员工名和对应上级领导都在同一个表中。这里,我们可以将一张表看做两张表。

(2)假设原始的emp为员工表,我们可以将这个表命名a;

(3)然后,我们手动整理出领导表,命名b;

员工的领导编号 = 领导的员工编号(领导的自身编号)

+-------+--------+
| empno | ename  |
+-------+--------+
|  7566 | JONES  |
|  7698 | BLAKE  |
|  7782 | CLARK  |
|  7788 | SCOTT  |
|  7839 | KING   |
|  7902 | FORD   |
+-------+--------+

因此:

select a.ename as '员工名', b.ename as '领导名' 
from emp a 
inner join emp b // inner可以省略
on a.mgr = b.empno;
+--------+--------+
| 员工名 | 领导名 |
+--------+--------+
| SMITH  | 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  |
+--------+--------+
上一篇:18.MySQL中的LIKE(模糊查询) 和 NOT LIKE


下一篇:oracle视图和索引