

在此小刘感谢大家的关注和支持,我一定坚持做好这套教程




SELECT d.deptno, d.dname, e.deptno, e.empno, e.enameFROM emp eCROSS JOIN dept d;




SQL> SELECT e.empno, e.ename, e.deptno, d.deptno, d.dname2 FROM emp e3 JOIN dept d4 ON (e.deptno = d.deptno);EMPNO ENAME DEPTNO DEPTNO DNAME----- ---------- ------ ------ --------------7369 SMITH 20 20 RESEARCH7499 ALLEN 30 30 SALES7521 WARD 30 30 SALES7566 JONES 20 20 RESEARCH7654 MARTIN 30 30 SALES7698 BLAKE 30 30 SALES7782 CLARK 10 10 ACCOUNTING7788 SCOTT 20 20 RESEARCH7839 KING 10 10 ACCOUNTING7844 TURNER 30 30 SALES7876 ADAMS 20 20 RESEARCH7900 JAMES 30 30 SALES7902 FORD 20 20 RESEARCH7934 MILLER 10 10 ACCOUNTING14 rows selected
当然,所谓实体表之间的内在联系,并不一定是类似主外键这样的等同联结,也可能是非等同的联结关系,换句话说就是使用不等号表达的联结关系
SQL> SELECT * FROM salgrade;GRADE LOSAL HISAL---------- ---------- ----------1 700 12002 1201 14003 1401 20004 2001 30005 3001 9999SQL> SELECT e.empno, e.ename, e.deptno, d.dname, e.sal, g.grade2 FROM emp e3 JOIN dept d4 ON (e.deptno = d.deptno)5 JOIN salgrade g6 ON (e.sal BETWEEN g.losal AND g.hisal);EMPNO ENAME DEPTNO DNAME SAL GRADE----- ---------- ------ -------------- --------- ----------7839 KING 10 ACCOUNTING 5000.00 57782 CLARK 10 ACCOUNTING 2450.00 47934 MILLER 10 ACCOUNTING 1300.00 27902 FORD 20 RESEARCH 3000.00 47788 SCOTT 20 RESEARCH 3000.00 47566 JONES 20 RESEARCH 2975.00 47876 ADAMS 20 RESEARCH 1100.00 17369 SMITH 20 RESEARCH 800.00 17698 BLAKE 30 SALES 2850.00 47844 TURNER 30 SALES 1500.00 37499 ALLEN 30 SALES 1600.00 37654 MARTIN 30 SALES 1250.00 27521 WARD 30 SALES 1250.00 27900 JAMES 30 SALES 950.00 114 rows selected
另外,在一些实际场景中,同一张表的不同行之间也可能有某种联系,这时,我们也可以在语句中重复多次引用这张表,实现不同行之间的关联
SQL> SELECT e.empno, e.ename, e.mgr, m.ename mname2 FROM emp e, emp m3 WHERE e.mgr = m.empno;EMPNO ENAME MGR MNAME----- ---------- ----- ----------7902 FORD 7566 JONES7788 SCOTT 7566 JONES7900 JAMES 7698 BLAKE7844 TURNER 7698 BLAKE7654 MARTIN 7698 BLAKE7521 WARD 7698 BLAKE7499 ALLEN 7698 BLAKE7934 MILLER 7782 CLARK7876 ADAMS 7788 SCOTT7782 CLARK 7839 KING7698 BLAKE 7839 KING7566 JONES 7839 KING7369 SMITH 7902 FORD13 rows selected
Oracle SQL 语法规则中,将表联结的写法进一步简化,它允许编码者将所要联结的表全部放置在 FROM 部分,并使用逗号相隔,至于表关联条件和数据筛选条件则均写在 WHERE 部分,数据库会自行将不同用处的条件语句区分以进行不同的操作

SQL> SELECT e.empno, e.ename, e.deptno, d.dname, e.sal, g.grade2 FROM emp e, dept d, salgrade g3 WHERE e.deptno = d.deptno -- join14 AND e.sal BETWEEN g.losal AND g.hisal -- join25 AND e.deptno = 30 -- filter16 AND g.grade = 3 -- filter27 /EMPNO ENAME DEPTNO DNAME SAL GRADE----- ---------- ------ -------------- --------- ----------7499 ALLEN 30 SALES 1600.00 37844 TURNER 30 SALES 1500.00 3



左外联结增加返回关键字 LEFT [OUTER] JOIN 以左表中不符合联结条件但符合筛选条件的行
右外联结增加返回关键字 RIGHT [OUTER] JOIN 以左表中不符合联结条件但符合筛选条件的行
全外联结则增加返回关键字 FULL [OUTER] JOIN 两边表中不符合联结条件但符合筛选条件的行
SQL> SELECT e.ename, e.deptno, d.deptno, d.dname2 FROM emp e3 LEFT JOIN dept d4 ON (e.deptno = d.deptno)5 WHERE e.deptno IN (10, 50);ENAME DEPTNO DEPTNO DNAME---------- ------ ------ --------------MILLER 10 10 ACCOUNTINGKING 10 10 ACCOUNTINGCLARK 10 10 ACCOUNTINGSCOTT 50
我们看到虽然 SCOTT 其部门编号 50 在 DEPT 表中没有对应记录,但是由于 EMP 是 LEFT JOIN 左边的表,且 SCOTT 这行数据符合了 WHERE 中对 EMP 表的筛选条件,所以它可以被返回,这一行中引用的 DEPT 表中的字段,都将得到 NULL
SQL> SELECT d.deptno, d.dname, e.empno, e.ename2 FROM emp e3 RIGHT JOIN dept d4 ON (e.deptno = d.deptno)5 WHERE d.deptno IN (10, 40);DEPTNO DNAME EMPNO ENAME------ -------------- ----- ----------10 ACCOUNTING 7782 CLARK10 ACCOUNTING 7839 KING10 ACCOUNTING 7934 MILLER40 OPERATIONS
我们看到尽管 40 号部门在 EMP 表中并没有对应的员工,但由于 DEPT 是 RIGHT JOIN 右边的表,而且这个部门符合了 WHERE 中对 DEPT 的筛选要求,所以它也可以被返回,同样地,这一行所引用的 EMP 表中的字段都是 NULL
SQL> SELECT d.deptno, d.dname, e.empno, e.ename2 FROM emp e3 FULL JOIN dept d4 ON (e.deptno = d.deptno);DEPTNO DNAME EMPNO ENAME------ -------------- ----- ----------20 RESEARCH 7369 SMITH30 SALES 7499 ALLEN30 SALES 7521 WARD20 RESEARCH 7566 JONES30 SALES 7654 MARTIN30 SALES 7698 BLAKE10 ACCOUNTING 7782 CLARK7788 SCOTT10 ACCOUNTING 7839 KING30 SALES 7844 TURNER20 RESEARCH 7876 ADAMS30 SALES 7900 JAMES20 RESEARCH 7902 FORD10 ACCOUNTING 7934 MILLER40 OPERATIONS15 rows selected
在这个例子返回的结果中,第 8 行展示了部门不能对应到 DEPT 表的 EMP 表中的 SCOTT 的行,第 15 行则展示了编号不能在 EMP 表匹配员工的 DEPT 表中的 40 号部门,这两行能够同时与内联结匹配成功的其它 13 行数据一起被返回,体现了全外联结 FULL JOIN 的作用

SQL> SELECT d.deptno, d.dname, e.empno, e.ename, e.sal, g.grade2 FROM emp e3 RIGHT JOIN dept d4 ON (e.deptno = d.deptno)5 JOIN salgrade g6 ON (e.sal BETWEEN g.losal AND g.hisal)7 WHERE d.deptno IN (10, 40);DEPTNO DNAME EMPNO ENAME SAL GRADE------ -------------- ----- ---------- --------- ----------10 ACCOUNTING 7839 KING 5000.00 510 ACCOUNTING 7782 CLARK 2450.00 410 ACCOUNTING 7934 MILLER 1300.00 2
我们观察到,这次结果中并没有返回 40 号部门,这是由于从语义上讲,EMP RIGHT JOIN DEPT 后,等同于形成了一个虚拟表,接下来与 SALGRADE 联结的是这张虚拟表,而非 EMP 表本身,只不过在这张虚拟表中,来源于 EMP 表的字段仍可带有其表别名
SQL> SELECT d.deptno, d.dname, e.empno, e.ename, e.sal, g.grade2 FROM emp e3 RIGHT JOIN dept d4 ON (e.deptno = d.deptno)5 LEFT JOIN salgrade g6 ON (e.sal BETWEEN g.losal AND g.hisal)7 WHERE d.deptno IN (10, 40);DEPTNO DNAME EMPNO ENAME SAL GRADE------ -------------- ----- ---------- --------- ----------40 OPERATIONS10 ACCOUNTING 7839 KING 5000.00 510 ACCOUNTING 7782 CLARK 2450.00 410 ACCOUNTING 7934 MILLER 1300.00 2

SQL> SELECT e.ename, e.deptno, d.deptno, d.dname2 FROM emp e, dept d3 WHERE e.deptno = d.deptno(+)4 AND e.deptno IN (10, 50);ENAME DEPTNO DEPTNO DNAME---------- ------ ------ --------------MILLER 10 10 ACCOUNTINGKING 10 10 ACCOUNTINGCLARK 10 10 ACCOUNTINGSCOTT 50SQL> SELECT d.deptno, d.dname, e.empno, e.ename2 FROM emp e, dept d3 WHERE e.deptno(+) = d.deptno4 AND d.deptno IN (10, 40);DEPTNO DNAME EMPNO ENAME------ -------------- ----- ----------10 ACCOUNTING 7782 CLARK10 ACCOUNTING 7839 KING10 ACCOUNTING 7934 MILLER40 OPERATIONS
另外,简化写法的查询语句也需要关注外联结的“传递性”
SQL> SELECT d.deptno, d.dname, e.empno, e.ename, e.sal, g.grade2 FROM emp e, dept d, salgrade g3 WHERE e.deptno(+) = d.deptno4 AND d.deptno IN (10, 40)5 AND e.sal BETWEEN g.losal AND g.hisal;DEPTNO DNAME EMPNO ENAME SAL GRADE------ -------------- ----- ---------- --------- ----------10 ACCOUNTING 7839 KING 5000.00 510 ACCOUNTING 7782 CLARK 2450.00 410 ACCOUNTING 7934 MILLER 1300.00 2SQL> SELECT d.deptno, d.dname, e.empno, e.ename, e.sal, g.grade2 FROM emp e, dept d, salgrade g3 WHERE e.deptno(+) = d.deptno4 AND d.deptno IN (10, 40)5 AND e.sal BETWEEN g.losal(+) AND g.hisal(+);DEPTNO DNAME EMPNO ENAME SAL GRADE------ -------------- ----- ---------- --------- ----------40 OPERATIONS10 ACCOUNTING 7839 KING 5000.00 510 ACCOUNTING 7782 CLARK 2450.00 410 ACCOUNTING 7934 MILLER 1300.00 2
如同这个例子中,EMP 表在和 SALGRADE 表关联时,我们可以理解为:EMP 表已经为 DEPT 表增加过一些空行了,所以 SALGRADE 表也要增加一些空行去和 EMP 表的空行关联
SQL> SELECT * FROM demo_a;COL---ABSQL> SELECT * FROM demo_b;COL---BSQL> SELECT * FROM demo_c;COL---BCSQL> --在11g环境中SQL> SELECT a.col, b.col, c.col2 FROM demo_a a, demo_b b, demo_c c3 WHERE a.col = b.col(+)4 AND b.col(+) = c.col;SELECT a.col, b.col, c.colFROM demo_a a, demo_b b, demo_c cWHERE a.col = b.col(+)*AND b.col(+) = c.colORA-01417: 表可以外部连接到至多一个其他的表SQL> --在12c环境中SQL> SELECT a.col, b.col, c.col2 FROM demo_a a, demo_b b, demo_c c3 WHERE a.col = b.col(+)4 AND b.col(+) = c.col;COL COL COL--- --- ---B B BB CA CA B
注意这个结果表明,DEMO_A 表先和 DEMO_C 表发生交叉联结,联结结果与 DEMO_B 表发生外联结,外联结的联结条件为“DEMO_A、DEMO_B 和 DEMO_C 的 COL 列同时相等”
SQL> SELECT a.col, b.col, c.col2 FROM demo_a a3 CROSS JOIN demo_c c4 LEFT JOIN demo_b b5 ON (a.col = b.col AND b.col = c.col);COL COL COL--- --- ---B B BB CA CA B

SQL> SELECT e.ename, e.deptno, d.deptno, d.dname2 FROM emp e3 LEFT JOIN dept d4 ON (e.deptno = d.deptno)5 WHERE d.deptno IN (10, 20);ENAME DEPTNO DEPTNO DNAME---------- ------ ------ --------------SMITH 20 20 RESEARCHJONES 20 20 RESEARCHCLARK 10 10 ACCOUNTINGKING 10 10 ACCOUNTINGADAMS 20 20 RESEARCHFORD 20 20 RESEARCHMILLER 10 10 ACCOUNTING7 rows selectedSQL> SELECT e.ename, e.deptno, d.deptno, d.dname2 FROM emp e3 LEFT JOIN dept d4 ON (e.deptno = d.deptno AND d.deptno IN (10, 20));ENAME DEPTNO DEPTNO DNAME---------- ------ ------ --------------MILLER 10 10 ACCOUNTINGKING 10 10 ACCOUNTINGCLARK 10 10 ACCOUNTINGFORD 20 20 RESEARCHADAMS 20 20 RESEARCHJONES 20 20 RESEARCHSMITH 20 20 RESEARCHSCOTT 50JAMES 30TURNER 30BLAKE 30MARTIN 30WARD 30ALLEN 3014 rows selected
如例一中,WHERE 语句中的条件是作用于前面 EMP 表左外联结 DEPT 表后的结果集的;又如例二中,SCOTT 这一行是因为其 DEPTNO 列不符合 E.DEPTNO=D.DEPTNO 这一半联结条件,此后的行是因为其虽然满足了前一半联结条件,但没有满足后一半条件 D.DEPTNO IN (10, 20),它们都可以被返回,因为这是外联结
SQL> SELECT e.ename, e.deptno, d.deptno, d.dname2 FROM emp e, dept d3 WHERE e.deptno = d.deptno(+)4 AND d.deptno IN (10, 20);ENAME DEPTNO DEPTNO DNAME---------- ------ ------ --------------SMITH 20 20 RESEARCHJONES 20 20 RESEARCHCLARK 10 10 ACCOUNTINGKING 10 10 ACCOUNTINGADAMS 20 20 RESEARCHFORD 20 20 RESEARCHMILLER 10 10 ACCOUNTING7 rows selectedSQL> SELECT e.ename, e.deptno, d.deptno, d.dname2 FROM emp e, dept d3 WHERE e.deptno = d.deptno(+)4 AND d.deptno(+) IN (10, 20);ENAME DEPTNO DEPTNO DNAME---------- ------ ------ --------------MILLER 10 10 ACCOUNTINGKING 10 10 ACCOUNTINGCLARK 10 10 ACCOUNTINGFORD 20 20 RESEARCHADAMS 20 20 RESEARCHJONES 20 20 RESEARCHSMITH 20 20 RESEARCHSCOTT 50JAMES 30TURNER 30BLAKE 30MARTIN 30WARD 30ALLEN 3014 rows selected



我刘某人就是天下第一长的男人





