自然连接(NATURAL JOIN)是一种特殊的等值连接,将表中具有相同名称的列自动进行匹配。
1.自然连接不必指定任何连接条件。
SQL> desc emp
Name Null? Type
----------------- -------- ------------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
SQL> desc dept
Name Null? Type
------------------ -------- ------------------
DEPTNO NOT NULL NUMBER(2)
DNAME VARCHAR2(14)
LOC VARCHAR2(13)
以上两张表中,有deptno这列名字相同,而且数据类型一致。
SQL> select *
2 from emp natural join dept;
DEPTNO EMPNO ENAME JOB MGR HIREDATE SAL COMM DNAME LOC
---------- ---------- ---------- ---------- ---------- ------------ ---------- ---------- ---------- ---------
10 7782 CLARK MANAGER 7839 09-JUN-81 2450 ACCOUNTING NEW YORK
10 7839 KING PRESIDENT 17-NOV-81 5000 ACCOUNTING NEW YORK
10 7934 MILLER CLERK 7782 23-JAN-82 1300 ACCOUNTING NEW YORK
20 7566 JONES MANAGER 7839 02-APR-81 2975 RESEARCH DALLAS
20 7902 FORD ANALYST 7566 03-DEC-81 3000 RESEARCH DALLAS
20 7876 ADAMS CLERK 7788 23-MAY-87 1100 RESEARCH DALLAS
20 7369 SMITH CLERK 7902 17-DEC-80 800 RESEARCH DALLAS
20 7788 SCOTT ANALYST 7566 19-APR-87 3000 RESEARCH DALLAS
30 7521 WARD SALESMAN 7698 22-FEB-81 1250 500 SALES CHICAGO
30 7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 SALES CHICAGO
30 7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 SALES CHICAGO
30 7900 JAMES CLERK 7698 03-DEC-81 950 SALES CHICAGO
30 7698 BLAKE MANAGER 7839 01-MAY-81 2850 SALES CHICAGO
30 7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 SALES CHICAGO
14 rows selected.
自然连接之后,两张表等值连接,DEPTNO这列自动合并成一列。
2.如果两张表中有相同名字的列,但是数据类型不一致,如果能隐式转换,则能正常连接,但如果隐式转换不成功,则报错。
SQL> create table emp2 as select * from emp;
Table created.
SQL> create table dept2 as select * from dept;
Table created.
SQL> alter table emp2 modify deptno number(10);
Table altered.
SQL> select * from emp2 natural join dept2;
DEPTNO EMPNO ENAME JOB MGR HIREDATE SAL COMM DNAME LOC
---------- ---------- ---------- ---------- ---------- ------------ ---------- ---------- ---------- ---------
20 7369 SMITH CLERK 7902 17-DEC-80 800 RESEARCH DALLAS
30 7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 SALES CHICAGO
30 7521 WARD SALESMAN 7698 22-FEB-81 1250 500 SALES CHICAGO
20 7566 JONES MANAGER 7839 02-APR-81 2975 RESEARCH DALLAS
30 7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 SALES CHICAGO
30 7698 BLAKE MANAGER 7839 01-MAY-81 2850 SALES CHICAGO
10 7782 CLARK MANAGER 7839 09-JUN-81 2450 ACCOUNTING NEW YORK
20 7788 SCOTT ANALYST 7566 19-APR-87 3000 RESEARCH DALLAS
10 7839 KING PRESIDENT 17-NOV-81 5000 ACCOUNTING NEW YORK
30 7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 SALES CHICAGO
20 7876 ADAMS CLERK 7788 23-MAY-87 1100 RESEARCH DALLAS
30 7900 JAMES CLERK 7698 03-DEC-81 950 SALES CHICAGO
20 7902 FORD ANALYST 7566 03-DEC-81 3000 RESEARCH DALLAS
10 7934 MILLER CLERK 7782 23-JAN-82 1300 ACCOUNTING NEW YORK
14 rows selected.
上例中,emp2和dept2两张表,有一个同名的列deptno,dept2中,deptno列是number(2),emp2列中,deptno列是number(10),虽然长度不一致,但是也能正常匹配。
SQL> truncate table emp2;
Table truncated.
SQL> alter table emp2 modify deptno varchar2(10);
Table altered.
SQL> insert into emp2(empno,ename,deptno) select empno,ename,to_char(deptno) from emp;
14 rows created.
SQL> select * from emp2 natural join dept2;
DEPTNO EMPNO ENAME JOB MGR HIREDATE SAL COMM DNAME LOC
---------- ---------- ---------- ---------- ---------- ------------ ---------- ---------- ---------- ---------
20 7369 SMITH RESEARCH DALLAS
30 7499 ALLEN SALES CHICAGO
30 7521 WARD SALES CHICAGO
20 7566 JONES RESEARCH DALLAS
30 7654 MARTIN SALES CHICAGO
30 7698 BLAKE SALES CHICAGO
10 7782 CLARK ACCOUNTING NEW YORK
20 7788 SCOTT RESEARCH DALLAS
10 7839 KING ACCOUNTING NEW YORK
30 7844 TURNER SALES CHICAGO
20 7876 ADAMS RESEARCH DALLAS
30 7900 JAMES SALES CHICAGO
20 7902 FORD RESEARCH DALLAS
10 7934 MILLER ACCOUNTING NEW YORK
14 rows selected.
上例中,emp2和dept2列中同名的列deptno,在emp2列是,是varchar2(10)类型,在dept2列是,是number(2),但是,列中的数据,在匹配时能自动隐式转换,所以也能正常匹配。
SQL> insert into emp2(empno,ename,deptno) values(1234,'Hello','abc');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from emp2 natural join dept2;
ERROR:
ORA-01722: invalid number
no rows selected
上例中,在emp2的deptno列中,插入了一个字符'abc',这个就不能再隐式转换成数字了,所以报错。
3.使用自然连接时,不能使用表名或表的别名修饰列。
SQL> select ename,deptno,dname
2 from emp natural join dept;
ENAME DEPTNO DNAME
---------- ---------- ----------
CLARK 10 ACCOUNTING
KING 10 ACCOUNTING
MILLER 10 ACCOUNTING
JONES 20 RESEARCH
FORD 20 RESEARCH
ADAMS 20 RESEARCH
SMITH 20 RESEARCH
SCOTT 20 RESEARCH
WARD 30 SALES
TURNER 30 SALES
ALLEN 30 SALES
JAMES 30 SALES
BLAKE 30 SALES
MARTIN 30 SALES
14 rows selected.
SQL> select emp.ename,emp.deptno,dept.dname
2 from emp natural join dept;
select emp.ename,emp.deptno,dept.dname
*
ERROR at line 1:
ORA-25155: column used in NATURAL join cannot have qualifier
SQL> select e.ename,e.deptno,d.dname
2 from emp e natural join dept d;
select e.ename,e.deptno,d.dname
*
ERROR at line 1:
ORA-25155: column used in NATURAL join cannot have qualifier
4.自然连接会两张表中相同名称的所有列。
SQL> conn hr/hr
SQL> desc employees
Name Null? Type
------------------------ -------- -------------
EMPLOYEE_ID NOT NULL NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL VARCHAR2(25)
EMAIL NOT NULL VARCHAR2(25)
PHONE_NUMBER VARCHAR2(20)
HIRE_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
SALARY NUMBER(8,2)
COMMISSION_PCT NUMBER(2,2)
MANAGER_ID NUMBER(6)
DEPARTMENT_ID NUMBER(4)
SQL> desc departments
Name Null? Type
---------------------- -------- --------------
DEPARTMENT_ID NOT NULL NUMBER(4)
DEPARTMENT_NAME NOT NULL VARCHAR2(30)
MANAGER_ID NUMBER(6)
LOCATION_ID NUMBER(4)
两张表,有两列列名相同,DEPARTMENT_ID和MANAGER_ID 列,并且数据类型一致。
SQL> col last_name for a10
SQL> col first_name for a12
SQL> col email for a12
SQL> col PHONE_NUMBER for a20
SQL> col DEPARTMENT_NAME for a15
SQL> col JOB_ID for a10
SQL> select *
2 from employees natural join departments;
MANAGER_ID DEPARTMENT_ID EMPLOYEE_ID FIRST_NAME LAST_NAME EMAIL PHONE_NUMBER HIRE_DATE JOB_ID SALARY COMMISSION_PCT DEPARTMENT_NAME LOCATION_ID
---------- ------------- ----------- ------------ ---------- ------------ -------------------- ------------ ---------- ---------- -------------- --------------- -----------
201 20 202 Pat Fay PFAY 603.123.6666 17-AUG-97 MK_REP 6000 Marketing 1800
205 110 206 William Gietz WGIETZ 515.123.8181 07-JUN-94 AC_ACCOUNT 8300 Accounting 1700
100 90 101 Neena Kochhar NKOCHHAR 515.123.4568 21-SEP-89 AD_VP 17000 Executive 1700
100 90 102 Lex De Haan LDEHAAN 515.123.4569 13-JAN-93 AD_VP 17000 Executive 1700
103 60 104 Bruce Ernst BERNST 590.423.4568 21-MAY-91 IT_PROG 6000 IT 1400
103 60 105 David Austin DAUSTIN 590.423.4569 25-JUN-97 IT_PROG 4800 IT 1400
103 60 106 Valli Pataballa VPATABAL 590.423.4560 05-FEB-98 IT_PROG 4800 IT 1400
103 60 107 Diana Lorentz DLORENTZ 590.423.5567 07-FEB-99 IT_PROG 4200 IT 1400
108 100 109 Daniel Faviet DFAVIET 515.124.4169 16-AUG-94 FI_ACCOUNT 9000 Finance 1700
108 100 110 John Chen JCHEN 515.124.4269 28-SEP-97 FI_ACCOUNT 8200 Finance 1700
108 100 111 Ismael Sciarra ISCIARRA 515.124.4369 30-SEP-97 FI_ACCOUNT 7700 Finance 1700
108 100 112 Jose Manuel Urman JMURMAN 515.124.4469 07-MAR-98 FI_ACCOUNT 7800 Finance 1700
108 100 113 Luis Popp LPOPP 515.124.4567 07-DEC-99 FI_ACCOUNT 6900 Finance 1700
114 30 115 Alexander Khoo AKHOO 515.127.4562 18-MAY-95 PU_CLERK 3100 Purchasing 1700
114 30 116 Shelli Baida SBAIDA 515.127.4563 24-DEC-97 PU_CLERK 2900 Purchasing 1700
114 30 117 Sigal Tobias STOBIAS 515.127.4564 24-JUL-97 PU_CLERK 2800 Purchasing 1700
114 30 118 Guy Himuro GHIMURO 515.127.4565 15-NOV-98 PU_CLERK 2600 Purchasing 1700
114 30 119 Karen Colmenares KCOLMENA 515.127.4566 10-AUG-99 PU_CLERK 2500 Purchasing 1700
121 50 129 Laura Bissot LBISSOT 650.124.5234 20-AUG-97 ST_CLERK 3300 Shipping 1500
121 50 130 Mozhe Atkinson MATKINSO 650.124.6234 30-OCT-97 ST_CLERK 2800 Shipping 1500
121 50 131 James Marlow JAMRLOW 650.124.7234 16-FEB-97 ST_CLERK 2500 Shipping 1500
121 50 132 TJ Olson TJOLSON 650.124.8234 10-APR-99 ST_CLERK 2100 Shipping 1500
145 80 150 Peter Tucker PTUCKER 011.44.1344.129268 30-JAN-97 SA_REP 10000 .3 Sales 2500
145 80 151 David Bernstein DBERNSTE 011.44.1344.345268 24-MAR-97 SA_REP 9500 .25 Sales 2500
145 80 152 Peter Hall PHALL 011.44.1344.478968 20-AUG-97 SA_REP 9000 .25 Sales 2500
145 80 153 Christopher Olsen COLSEN 011.44.1344.498718 30-MAR-98 SA_REP 8000 .2 Sales 2500
145 80 154 Nanette Cambrault NCAMBRAU 011.44.1344.987668 09-DEC-98 SA_REP 7500 .2 Sales 2500
145 80 155 Oliver Tuvault OTUVAULT 011.44.1344.486508 23-NOV-99 SA_REP 7000 .15 Sales 2500
121 50 184 Nandita Sarchand NSARCHAN 650.509.1876 27-JAN-96 SH_CLERK 4200 Shipping 1500
121 50 185 Alexis Bull ABULL 650.509.2876 20-FEB-97 SH_CLERK 4100 Shipping 1500
121 50 186 Julia Dellinger JDELLING 650.509.3876 24-JUN-98 SH_CLERK 3400 Shipping 1500
121 50 187 Anthony Cabrio ACABRIO 650.509.4876 07-FEB-99 SH_CLERK 3000 Shipping 1500
32 rows selected.
5.自然连接也可以指定显示列。
SQL> select EMPLOYEE_ID,FIRST_NAME,DEPARTMENT_ID,DEPARTMENT_NAME
2 from employees natural join departments;
EMPLOYEE_ID FIRST_NAME DEPARTMENT_ID DEPARTMENT_NAME
----------- ------------ ------------- ---------------
202 Pat 20 Marketing
206 William 110 Accounting
101 Neena 90 Executive
102 Lex 90 Executive
104 Bruce 60 IT
105 David 60 IT
106 Valli 60 IT
107 Diana 60 IT
109 Daniel 100 Finance
110 John 100 Finance
111 Ismael 100 Finance
112 Jose Manuel 100 Finance
113 Luis 100 Finance
115 Alexander 30 Purchasing
116 Shelli 30 Purchasing
117 Sigal 30 Purchasing
118 Guy 30 Purchasing
119 Karen 30 Purchasing
129 Laura 50 Shipping
130 Mozhe 50 Shipping
131 James 50 Shipping
132 TJ 50 Shipping
150 Peter 80 Sales
151 David 80 Sales
152 Peter 80 Sales
153 Christopher 80 Sales
154 Nanette 80 Sales
155 Oliver 80 Sales
184 Nandita 50 Shipping
185 Alexis 50 Shipping
186 Julia 50 Shipping
187 Anthony 50 Shipping
32 rows selected.
和下面这个用内连接效果结果是一样的。
SQL> select e.EMPLOYEE_ID,e.FIRST_NAME,d.DEPARTMENT_ID,d.DEPARTMENT_NAME
2 from employees e,departments d
3 where e.department_id=d.department_id and e.MANAGER_ID=d.MANAGER_ID;
EMPLOYEE_ID FIRST_NAME DEPARTMENT_ID DEPARTMENT_N
----------- ------------ ------------- ------------
202 Pat 20 Marketing
206 William 110 Accounting
101 Neena 90 Executive
102 Lex 90 Executive
104 Bruce 60 IT
105 David 60 IT
106 Valli 60 IT
107 Diana 60 IT
109 Daniel 100 Finance
110 John 100 Finance
111 Ismael 100 Finance
112 Jose Manuel 100 Finance
113 Luis 100 Finance
115 Alexander 30 Purchasing
116 Shelli 30 Purchasing
117 Sigal 30 Purchasing
118 Guy 30 Purchasing
119 Karen 30 Purchasing
129 Laura 50 Shipping
130 Mozhe 50 Shipping
131 James 50 Shipping
132 TJ 50 Shipping
150 Peter 80 Sales
151 David 80 Sales
152 Peter 80 Sales
153 Christopher 80 Sales
154 Nanette 80 Sales
155 Oliver 80 Sales
184 Nandita 50 Shipping
185 Alexis 50 Shipping
186 Julia 50 Shipping
187 Anthony 50 Shipping
32 rows selected.
总结:
自然连接,自动匹配同名的列,虽然很方便,不用指定匹配的列。
但也有缺点,虽然可以指定查询结果包括哪些列,但不能人为地指定哪些列被匹配,而内连接就可以自由指定。
比如上例,用自然连接,就只能DEPARTMENT_ID和MANAGER_ID列都匹配,但用内连接,可以随意指定一个匹配,也可以指定两个都匹配,更加灵活。