《SQL CookBook 》笔记-第三章-多表查询-连接查询
1 内连接(inner join)
内连接又称为等值连接(equal join),他是基于两个表之间的某列相等来做连接。
内连接有隐式的连接和显式的连接,二者是一样的,只不过写法不一样。
1.1 隐式的内连接
使用where
子句
select e.ename,d.loc
from EMP as e,DEPT as d
where e.deptno=d.deptno
结果:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO DEPTNO DNAME LOC
----------- ---------- --------- ----------- ----------------------- ----------- ----------- ----------- ----------- -------------- -------------
7369 SMITH CLERK 7902 1980-12-17 00:00:00.000 800 NULL 20 20 RESEARCH DALLAS
7499 ALLEN SALESMAN 7698 1981-02-20 00:00:00.000 1600 300 30 30 SALES CHICAGO
7521 WARD SALESMAN 7698 1981-02-22 00:00:00.000 1250 500 30 30 SALES CHICAGO
7566 JONES MANAGER 7839 1981-04-02 00:00:00.000 2975 NULL 20 20 RESEARCH DALLAS
7654 MARTIN SALESMAN 7698 1981-09-28 00:00:00.000 1250 1400 30 30 SALES CHICAGO
7698 BLAKE MANAGER 7839 1981-05-01 00:00:00.000 2850 NULL 30 30 SALES CHICAGO
7782 CLARK MANAGER 7839 1981-06-09 00:00:00.000 2450 NULL 10 10 ACCOUNTING NEW YORK
7788 SCOTT ANALYST 7566 1982-12-09 00:00:00.000 3000 NULL 20 20 RESEARCH DALLAS
7839 KING PRESIDENT NULL 1981-11-17 00:00:00.000 5000 NULL 10 10 ACCOUNTING NEW YORK
7844 TURNER SALESMAN 7698 1981-09-08 00:00:00.000 1500 0 30 30 SALES CHICAGO
7876 ADAMS CLERK 7788 1983-01-12 00:00:00.000 1100 NULL 20 20 RESEARCH DALLAS
7900 JAMES CLERK 7698 1981-12-03 00:00:00.000 950 NULL 30 30 SALES CHICAGO
7902 FORD ANALYST 7566 1981-12-03 00:00:00.000 3000 NULL 20 20 RESEARCH DALLAS
7934 MILLER CLERK 7782 1982-01-23 00:00:00.000 1300 NULL 10 10 ACCOUNTING NEW YORK
(14 行受影响)
1.2 显式的内连接
显示的内连接使用inner join
连接两个表,使用on
子句做连接条件。
select e.ename,d.loc
from EMP as e inner join DEPT as d
on e.deptno=d.deptno
结果如上,和隐式的内连接是一样的。
2 外连接(outer join)
外连不但返回符合连接和查询条件的数据行,还返回不符合条件的一些行。
2.1 左连接(left outer join)
左向外联接的结果集包括 LEFT OUTER子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值。
例如:
select d.*,e.*
from dept d left outer join emp e
on (d.deptno = e.deptno)
结果将返回左侧表dept的所有行
结果:
DEPTNO DNAME LOC EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----------- -------------- ------------- ----------- ---------- --------- ----------- ----------------------- ----------- ----------- -----------
10 ACCOUNTING NEW YORK 7782 CLARK MANAGER 7839 1981-06-09 00:00:00.000 2450 NULL 10
10 ACCOUNTING NEW YORK 7839 KING PRESIDENT NULL 1981-11-17 00:00:00.000 5000 NULL 10
10 ACCOUNTING NEW YORK 7934 MILLER CLERK 7782 1982-01-23 00:00:00.000 1300 NULL 10
20 RESEARCH DALLAS 7369 SMITH CLERK 7902 1980-12-17 00:00:00.000 800 NULL 20
20 RESEARCH DALLAS 7566 JONES MANAGER 7839 1981-04-02 00:00:00.000 2975 NULL 20
20 RESEARCH DALLAS 7788 SCOTT ANALYST 7566 1982-12-09 00:00:00.000 3000 NULL 20
20 RESEARCH DALLAS 7876 ADAMS CLERK 7788 1983-01-12 00:00:00.000 1100 NULL 20
20 RESEARCH DALLAS 7902 FORD ANALYST 7566 1981-12-03 00:00:00.000 3000 NULL 20
30 SALES CHICAGO 7499 ALLEN SALESMAN 7698 1981-02-20 00:00:00.000 1600 300 30
30 SALES CHICAGO 7521 WARD SALESMAN 7698 1981-02-22 00:00:00.000 1250 500 30
30 SALES CHICAGO 7654 MARTIN SALESMAN 7698 1981-09-28 00:00:00.000 1250 1400 30
30 SALES CHICAGO 7698 BLAKE MANAGER 7839 1981-05-01 00:00:00.000 2850 NULL 30
30 SALES CHICAGO 7844 TURNER SALESMAN 7698 1981-09-08 00:00:00.000 1500 0 30
30 SALES CHICAGO 7900 JAMES CLERK 7698 1981-12-03 00:00:00.000 950 NULL 30
40 OPERATIONS BOSTON NULL NULL NULL NULL NULL NULL NULL NULL
(15 行受影响)
2.2 右连接(right outer join)
右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。
例如:
select e.*,d.*
from emp e right outer join dept d
on e.deptno= d.deptno
结果将返回右侧表dept的所有行
结果:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO DEPTNO DNAME LOC
----------- ---------- --------- ----------- ----------------------- ----------- ----------- ----------- ----------- -------------- -------------
7782 CLARK MANAGER 7839 1981-06-09 00:00:00.000 2450 NULL 10 10 ACCOUNTING NEW YORK
7839 KING PRESIDENT NULL 1981-11-17 00:00:00.000 5000 NULL 10 10 ACCOUNTING NEW YORK
7934 MILLER CLERK 7782 1982-01-23 00:00:00.000 1300 NULL 10 10 ACCOUNTING NEW YORK
7369 SMITH CLERK 7902 1980-12-17 00:00:00.000 800 NULL 20 20 RESEARCH DALLAS
7566 JONES MANAGER 7839 1981-04-02 00:00:00.000 2975 NULL 20 20 RESEARCH DALLAS
7788 SCOTT ANALYST 7566 1982-12-09 00:00:00.000 3000 NULL 20 20 RESEARCH DALLAS
7876 ADAMS CLERK 7788 1983-01-12 00:00:00.000 1100 NULL 20 20 RESEARCH DALLAS
7902 FORD ANALYST 7566 1981-12-03 00:00:00.000 3000 NULL 20 20 RESEARCH DALLAS
7499 ALLEN SALESMAN 7698 1981-02-20 00:00:00.000 1600 300 30 30 SALES CHICAGO
7521 WARD SALESMAN 7698 1981-02-22 00:00:00.000 1250 500 30 30 SALES CHICAGO
7654 MARTIN SALESMAN 7698 1981-09-28 00:00:00.000 1250 1400 30 30 SALES CHICAGO
7698 BLAKE MANAGER 7839 1981-05-01 00:00:00.000 2850 NULL 30 30 SALES CHICAGO
7844 TURNER SALESMAN 7698 1981-09-08 00:00:00.000 1500 0 30 30 SALES CHICAGO
7900 JAMES CLERK 7698 1981-12-03 00:00:00.000 950 NULL 30 30 SALES CHICAGO
NULL NULL NULL NULL NULL NULL NULL NULL 40 OPERATIONS BOSTON
2.3 全外连接(full outer join)
完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。
例如:
select d.* ,e.*
from emp e full outer join dept d
on e.deptno= d.deptno
结果:
DEPTNO DNAME LOC EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----------- -------------- ------------- ----------- ---------- --------- ----------- ----------------------- ----------- ----------- -----------
20 RESEARCH DALLAS 7369 SMITH CLERK 7902 1980-12-17 00:00:00.000 800 NULL 20
30 SALES CHICAGO 7499 ALLEN SALESMAN 7698 1981-02-20 00:00:00.000 1600 300 30
30 SALES CHICAGO 7521 WARD SALESMAN 7698 1981-02-22 00:00:00.000 1250 500 30
20 RESEARCH DALLAS 7566 JONES MANAGER 7839 1981-04-02 00:00:00.000 2975 NULL 20
30 SALES CHICAGO 7654 MARTIN SALESMAN 7698 1981-09-28 00:00:00.000 1250 1400 30
30 SALES CHICAGO 7698 BLAKE MANAGER 7839 1981-05-01 00:00:00.000 2850 NULL 30
10 ACCOUNTING NEW YORK 7782 CLARK MANAGER 7839 1981-06-09 00:00:00.000 2450 NULL 10
20 RESEARCH DALLAS 7788 SCOTT ANALYST 7566 1982-12-09 00:00:00.000 3000 NULL 20
10 ACCOUNTING NEW YORK 7839 KING PRESIDENT NULL 1981-11-17 00:00:00.000 5000 NULL 10
30 SALES CHICAGO 7844 TURNER SALESMAN 7698 1981-09-08 00:00:00.000 1500 0 30
20 RESEARCH DALLAS 7876 ADAMS CLERK 7788 1983-01-12 00:00:00.000 1100 NULL 20
30 SALES CHICAGO 7900 JAMES CLERK 7698 1981-12-03 00:00:00.000 950 NULL 30
20 RESEARCH DALLAS 7902 FORD ANALYST 7566 1981-12-03 00:00:00.000 3000 NULL 20
10 ACCOUNTING NEW YORK 7934 MILLER CLERK 7782 1982-01-23 00:00:00.000 1300 NULL 10
40 OPERATIONS BOSTON NULL NULL NULL NULL NULL NULL NULL NULL
(15 行受影响)
3 自连接(self-join)
自连接是连接的一种用法,但并不是连接的一种类型,因为他的本质是把一张表当成两张表来使用。
使用自连接就伴随着使用表的别名,可以给同一张表起不同的别名,所以一张表可以当作几张表来用。
自连接的一个重要作用就是可以代替对一张表的多次查询(嵌套子查询)。
举一个简单的例子:
有一张顾客表Customers,三列,分别是订货公司的标号,名字,和联系人
其中有一个订货公司3有两个联系人,分别是小红和小亮
Customers表
cust_no | cust_name | cust_contact |
---|---|---|
001 | 公司1 | 小明 |
002 | 公司2 | 小亮 |
003 | 公司3 | 小红 |
004 | 公司3 | 小军 |
先在要找到小红公司的所有联系人
select cust_contact
from Cumstomers
where cust_name=
(
select cust_name
from Customers
where cust_contact='小红'
)
结果:
cust_name |
---|
小红 |
小亮 |
我们其实可以使用自查询
select c1.cust_contact
from Cumstomers c1,Cumstomers c2
where c1.cust_name=c2.cust_name
and c2.cust_contact='小红'
结果:
cust_name |
---|
小红 |
小亮 |
注意上面的SQL语句是查询的c1表中的列
注意c1和c2在中表的顺序(和直觉是不一样的)
其中中间表是
cust_no | cust_name | cust_contact | cust_no | cust_name | cust_contact |
---|---|---|---|---|---|
001 | 公司1 | 小明 | 001 | 公司1 | 小明 |
002 | 公司2 | 小亮 | 002 | 公司2 | 小亮 |
003 | 公司3 | 小红 | 003 | 公司3 | 小红 |
004 | 公司3 | 小军 | 003 | 公司3 | 小红 |
003 | 公司3 | 小红 | 004 | 公司3 | 小军 |
004 | 公司3 | 小军 | 004 | 公司3 | 小军 |
4 自然连接(natural join)
无论何时对表进行联结,应该至少有一列不止出现在一个表中(被联结的列)。标准的联结(内联结)返回所有数据,相同的列甚至多次出现。自然联结排除相同列的多次出现,使每一列只返回一次。
5 交叉连接(cross join)
交叉连接是不带WHERE条件子句,它将会返回被连接的两个表的笛卡尔积,返回结果的行数等于两个表行数的乘积