多表查询
完整命令格式:
连接方式
- 内连接:
INNER JOIN
简写JOIN
- 外连接:
LEFT JOIN
和RIGHT JOIN
- 自连接:一张表的连接,可以内连接也可以外连接
内连接
两张表与连接条件相匹配的行留下,任意一张表中不满足条件的行都去除。
没有连接条件时,表1中的一条记录会定影另一张表中的所有记录。
SELECT tb1.a,tb1.b,tb2.aa,tb2.bb
FROM tb1 JOIN tb2
ON a>aa;
例子:查看员工工作地点
SELECT emp.ename,emp.deptno,dept.deptno,dept.loc
FROM emp JOIN dept
ON emp.deptno=dept.deptno ;
例子:显示每个员工的工资等级
SELECT emp.ename AS '员工',salgrade.grade AS '工资等级'
FROM emp JOIN salgrade
ON emp.sal BETWEEN salgrade.losal AND salgrade.hisal
ORDER BY salgrade.grade DESC;
例子:显示每个工作地点的员工的人数
SELECT dept.loc,COUNT(*)
FROM emp JOIN dept
ON emp.deptno = dept.deptno
GROUP BY dept.loc;
外连接
左外连接:两张表与连接条件相匹配的行留下,左表中不满足条件的行也会被留下来,右表中不满足条件的行被去除。右表中没有对应值的NULL
来填充。
SELECT *
FROM 表1 LEFT JOIN 表2
ON 连接条件;
右外连接:两张表与连接条件相匹配的行留下,右表中不满足条件的行也>会被留下来,左表中不满足条件的行被去除。左表中没有对应值的NULL
来填充。
SELECT *
FROM 表1 LEFT JOIN 表2
ON 连接条件;
左外和右外本质相同,实际使用看业务需求。哪边显示哪边外。
使用案例:
SELECT dept.dname,IF(emp.deptno IS NULL,0,COUNT(*))
FROM dept LEFT JOIN emp
ON dept.deptno=emp.deptno
GROUP BY dept.dname;
自连接
一张表的连接,可以内连接也可以外连接。
使用案例:员工表中每个员工都有一个领导,使用领导的员工编号代替,需要显示每个员工的领导姓名。
举个例子:显示所有员工能的领导信息。
表自连接通过别名区分表
SELECT e.ename,e.mgr,m.empno,m.ename
FROM emp AS e LEFT JOIN emp AS m
ON e.mgr=m.empno;
再来个例子:显示每个员工和其他员工工资的比对表
连接条件:根据编号大小,编号小的员工已经产生了对应编号大的员工的关系,后面的员工比对时不用考虑比自己编号小的员工的数据。
SELECT a.ename,a.sal,b.ename,b.sal
FROM emp AS a JOIN emp AS b
ON a.empno < b.empno;
再来个例子:显示员工中工资比关羽高的员工
SELECT a.ename,a.sal,b.ename,b.sal
FROM emp AS a JOIN emp AS b
ON a.empno != b.empno
WHERE a.ename='关羽' && a.sal
再来个例子巩固一下:显示员工对应的工资等级
SELECT ename,loc,grade
FROM emp JOIN dept JOIN salgrade
ON emp.deptno=dept.deptno && sal BETWEEN losal AND hisal;