1、什么是连接查询
在实际开发中,大部分的情况下都不是从单表查询数据,一般都是多张表联合查询 取出最终的结果。
在实际开发中,一般一个业务都会对应多张表,比如:学生和班级,起码两张表
2、连接查询的分类?
根据语法出现的年代来划分的,包括:
SQL92 (一些老的DBA可能还在使用这种语法,数据管理员)
SQL99
根据表的连接方式来划分,包括:
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接
右外连接
全连接(很少用)
3、在标的连接查询方面有一种现象被称为:笛卡尔积现象(笛卡尔乘积现象)
案例:找出每一个员工的部门名称,要求显示员工名和部门名。
EMP表:
mysql> select ename,deptno from emp;
+————+————+
| ename | deptno |
+————+————+
| SMITH | 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 |
+————+————+
DEPT表
mysql> select * from dept;
+————+——————+—————+
| DEPTNO | DNAME | LOC |
+————+——————+—————+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+————+——————+—————+
select ename,dname from emp,dept; //ename和dname要联合一起显示,粘到一块。
+————+——————+
| ename | dname |
+————+——————+
| SMITH | OPERATIONS |
| SMITH | SALES |
| SMITH | RESEARCH |
| SMITH | ACCOUNTING |
| ALLEN | OPERATIONS |
| ALLEN | SALES |
| ALLEN | RESEARCH |
| ALLEN | ACCOUNTING |
。。。。。。
56 rows in set (0.00 sec)
笛卡尔积现象:当两张表进行连接查询的时候,没有任何条件进行限制,最终的查 询结果条数是两张表记录条数的乘积。
关于表的别名:
select e.ename,d.dname from emp e,dept d;
表的别名有什么好处?
第一:执行效率高。
第二:可读性好。
4、怎么避免笛卡尔积现象?当然是加条件进行过滤。
思考:避免了笛卡尔积现象,会减少记录的匹配次数吗?
不会,次数还是56次。只不过显示的是有效记录。
案例:找出每一个员工的部门名称,要求显示员工名和部门名。
select e.ename,d.dname from emp e,dept d where e.deptno = d.deptno; //SQL92,以后不用
+————+——————+
| ename | dname |
+————+——————+
| SMITH | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCH |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCH |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCH |
| JAMES | SALES |
| FORD | RESEARCH |
| MILLER | ACCOUNTING |
+————+——————+
内连接之等值连接
最大特点是:条件是等量关系。
案例:找出每一个员工的部门名称,要求显示员工名和部门名。
SQL92:select (太老了,不用了)
e.ename,d.dname
from
emp e,dept d
where
e.deptno = d.deptno;
SQL99:(常用的)
select
e.ename,d.dname
from
emp e
inner join
dept d
on
e.deptno = d.deptno;
//inner 可以省略的,带着inner目的是可读性好一些。
语法:
。。。
A
inner join
B
on
连接条件
where
。。。
SQL99语法结构更清晰一些:表的连接条件和后来的where条件分离了
+————+——————+
| ename | dname |
+————+——————+
| SMITH | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCH |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCH |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCH |
| JAMES | SALES |
| FORD | RESEARCH |
| MILLER | ACCOUNTING |
+————+——————+
内连接之非等连接
最大的特点是:连接条件中的关系是非等量关系。
案例:找出每个员工的工资等级,要求显示员工名、工资、工资等级。
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 |
+————+————-+
select * from salgrade;
+———-+———-+———-+
| GRADE | LOSAL | HISAL |
+———-+———-+———-+
| 1 | 700 | 1200 |
| 2 | 1201 | 1400 |
| 3 | 1401 | 2000 |
| 4 | 2001 | 3000 |
| 5 | 3001 | 9999 |
+———-+———-+———-+
mysql> select e.ename,e.sal,s.grade from emp e join salgrade s 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 |
+————+————-+———-+
内连接之自连接
最大的特点是:一张表看做两张表。自己连接自己
案例:找出每个员工的上级领导,要求显示员工名和对应的领导名。
mysql> select empno,ename,mgr from emp;
emp A 员工表
+———-+————+———+
| empno | ename | 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 |
+———-+————+———+
emp B 领导表
+———-+————+———+
| empno | ename | mgr |
+———-+————+———+
| 7566 | JONES | 7839 |
| 7698 | BLAKE | 7839 |
| 7782 | CLARK | 7839 |
| 7788 | SCOTT | 7566 |
| 7839 | KING | NULL |
| 7902 | FORD | 7566 |
+———-+————+———+
员工的领导编号 = 领导的员工编号
mysql> select a.ename,b.ename from emp a inner join emp b on a.mgr = b.empno;
+————+———-+
| ename | ename |
+————+———-+
| 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 |
+————+———-+
外连接
1、什么是外连接,和内连接有什么区别?
内连接:假设A和B表进行连接,使用内连接的话,凡是A表和B表能够匹配上的记录 查询出来,这就是内连接。AB两张表没有主副之分,两张表是平等的。
外连接:假设A和B表进行连接,使用外连接的话,AB两张表中有一张表是主表,
一张是副表,主要查询主表中的数据,捎带着查询副表,当副表中的数据 没有主表中的数据匹配上的,副表会自动生成NULL与之匹配。
2、外连接的分类?
左外连接(左连接):表示左边的这张表是主表。
右外连接(右连接):表示右边的这张表是主表。
左连接有右连接的写法,右连接也会有对应的左连接的写法。
案例:找出,每个员工的上级领导?(所有的员工必须都查询出来)
emp A 员工表
+———-+————+———+
| empno | ename | 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 |
+———-+————+———+
emp B 领导表
+———-+————+———+
| empno | ename | mgr |
+———-+————+———+
| 7566 | JONES | 7839 |
| 7698 | BLAKE | 7839 |
| 7782 | CLARK | 7839 |
| 7788 | SCOTT | 7566 |
| 7839 | KING | NULL |
| 7902 | FORD | 7566 |
+———-+————+———+
外连接:select a.ename ‘员工’,b.ename’领导’ from emp a left outer join emp b on a.mgr = b.empno;(左连接)//outer 可以省略。
+————+————+
| 员工 | 领导 |
+————+————+
| SMITH | 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 |
+————+————+
外连接最重要的特点是:主表的数据无条件的全部查询出来。
案例:找出那个部门没有员工?
mysql> select from emp;
EMP表
+———-+————+—————-+———+——————+————-+————-+————+
| 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 |
+———-+————+—————-+———+——————+————-+————-+————+
DEPT表
mysql> select from dept;
+————+——————+—————+
| DEPTNO | DNAME | LOC |
+————+——————+—————+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+————+——————+—————+
select d.* from emp e right join dept d on e.deptno = d.deptno where e.empno is null;
+————+——————+————+
| DEPTNO | DNAME | LOC |
+————+——————+————+
| 40 | OPERATIONS | BOSTON |
+————+——————+————+
3张表以上怎么连接查询
案例:找出每一个员工的部门名称以及工资等级。
EMP e
+———-+————+————+————-+
| empno | ename | deptno | sal |
+———-+————+————+————-+
| 7369 | SMITH | 20 | 800.00 |
| 7499 | ALLEN | 30 | 1600.00 |
| 7521 | WARD | 30 | 1250.00 |
| 7566 | JONES | 20 | 2975.00 |
| 7654 | MARTIN | 30 | 1250.00 |
| 7698 | BLAKE | 30 | 2850.00 |
| 7782 | CLARK | 10 | 2450.00 |
| 7788 | SCOTT | 20 | 3000.00 |
| 7839 | KING | 10 | 5000.00 |
| 7844 | TURNER | 30 | 1500.00 |
| 7876 | ADAMS | 20 | 1100.00 |
| 7900 | JAMES | 30 | 950.00 |
| 7902 | FORD | 20 | 3000.00 |
| 7934 | MILLER | 10 | 1300.00 |
+———-+————+————+————-+
DEPT表 d
+————+——————+—————+
| DEPTNO | DNAME | LOC |
+————+——————+—————+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+————+——————+—————+
SALGRADE表 s
+———-+———-+———-+
| GRADE | LOSAL | HISAL |
+———-+———-+———-+
| 1 | 700 | 1200 |
| 2 | 1201 | 1400 |
| 3 | 1401 | 2000 |
| 4 | 2001 | 3000 |
| 5 | 3001 | 9999 |
+———-+———-+———-+
注意:
。。。
A
join
B
jon
C
。。。
表示:A表和B表先进行表连接,连接之后A表继续和C表进行表连接。
mysql> select e.ename,d.dname,s.grade from emp e join dept d on e.deptno = d.deptno join salgrade s on e.sal between s.l
osal and s.hisal;
+————+——————+———-+
| ename | dname | grade |
+————+——————+———-+
| SMITH | RESEARCH | 1 |
| ALLEN | SALES | 3 |
| WARD | SALES | 2 |
| JONES | RESEARCH | 4 |
| MARTIN | SALES | 2 |
| BLAKE | SALES | 4 |
| CLARK | ACCOUNTING | 4 |
| SCOTT | RESEARCH | 4 |
| KING | ACCOUNTING | 5 |
| TURNER | SALES | 3 |
| ADAMS | RESEARCH | 1 |
| JAMES | SALES | 1 |
| FORD | RESEARCH | 4 |
| MILLER | ACCOUNTING | 2 |
+————+——————+———-+
案例:找出每一个员工的部门名称、工资等级以及上级领导。
mysql> select e.ename’员工’,d.dname,s.grade,b.ename’领导’ from
emp e
join
dept d
on
e.deptno = d.deptno
join
salgrade s
on
e.sal between s.losal and s.hisal
left join
emp b
on
e.mgr = b.empno;
