多表查詢
笛卡爾積:
笛卡爾積會在下面條件下產(chǎn)生:
省略連接條件
連接條件無效
所有表中的所有行互相連接
為了避免笛卡爾積荣回,可以在where加入有效的連接條件
在實際運行環(huán)境下涣雕,應(yīng)避免使用笛卡爾全集异旧。
連接的類型:
oracle的連接
等值連接
不等值連接
外連接
自連接
SQL99的連接
Cross joins
Natural joins
Using clause
Full or two sided outer joins
等值連接:
SQL> --等值連接
SQL> --查詢員工信息: 員工號 姓名 月薪 部門名稱
SQL> set linesize 80
SQL> desc dept
名稱 是否為空? 類型
----------------------------------------- -------- ----------------------------
DEPTNO NOT NULL NUMBER(2)
DNAME VARCHAR2(14)
LOC VARCHAR2(13)
SQL> select e.empno,e.ename,e.sal,d.dname
2 from emp e,dept d
3 where e.deptno=d.deptno;
EMPNO ENAME SAL DNAME
---------- ---------- ---------- --------------
7369 SMITH 800 RESEARCH
7499 ALLEN 1600 SALES
7521 WARD 1250 SALES
7566 JONES 2975 RESEARCH
7654 MARTIN 1250 SALES
7698 BLAKE 2850 SALES
7782 CLARK 2450 ACCOUNTING
7788 SCOTT 3000 RESEARCH
7839 KING 5000 ACCOUNTING
7844 TURNER 1500 SALES
7876 ADAMS 1100 RESEARCH
EMPNO ENAME SAL DNAME
---------- ---------- ---------- --------------
7900 JAMES 950 SALES
7902 FORD 3000 RESEARCH
7934 MILLER 1300 ACCOUNTING
不等值連接:
SQL> --不等值連接
SQL> --查詢員工信息: 員工號 姓名 月薪 工資級別
SQL> select * from salgrade;
GRADE LOSAL HISAL
---------- ---------- ----------
1 700 1200
2 1201 1400
3 1401 2000
4 2001 3000
5 3001 9999
SQL> select e.empno,e.ename,e.sal,s.grade
2 from emp e,salgrade s
3 where e.sal between s.losal and s.hisal;
EMPNO ENAME SAL GRADE
---------- ---------- ---------- ----------
7369 SMITH 800 1
7900 JAMES 950 1
7876 ADAMS 1100 1
7521 WARD 1250 2
7654 MARTIN 1250 2
7934 MILLER 1300 2
7844 TURNER 1500 3
7499 ALLEN 1600 3
7782 CLARK 2450 4
7698 BLAKE 2850 4
7566 JONES 2975 4
EMPNO ENAME SAL GRADE
---------- ---------- ---------- ----------
7788 SCOTT 3000 4
7902 FORD 3000 4
7839 KING 5000 5
外連接:
連接n個表凡恍,至少需要n-1個連接條件。
SQL> --外連接
SQL> --按部門統(tǒng)計員工人數(shù):部門號 部門名稱 人數(shù)
SQL> select d.deptno 部門號,d.dname 部門名稱,count(e.empno) 人數(shù)
2 from emp e,dept d
3 where e.deptno=d.deptno
4 group by d.deptno,d.dname;
部門號 部門名稱 人數(shù)
---------- -------------- ----------
10 ACCOUNTING 3
20 RESEARCH 5
30 SALES 6
SQL> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL> select * from emp where deptno=40;
未選定行
希望: 對于某些不成立的記錄点额,任然希望包含在最后的結(jié)果中
使用外連接:
左外連接:當(dāng)where e.deptno=d.deptno不成立的時候咪啡,等號左邊的表任然被包含
寫法:where e.deptno=d.deptno(+)
右外連接:當(dāng)where e.deptno=d.deptno不成立的時候,等號右邊的表任然被包含
寫法: where e.deptno(+)=d.deptno
例:
SQL> select d.deptno 部門號,d.dname 部門名稱,count(e.empno) 人數(shù)
2 from emp e,dept d
3 where e.deptno(+)=d.deptno
4 group by d.deptno,d.dname;
部門號 部門名稱 人數(shù)
---------- -------------- ----------
10 ACCOUNTING 3
40 OPERATIONS 0
20 RESEARCH 5
30 SALES 6
自連接:
SQL> --自連接
SQL> select e.ename 員工姓名,b.ename 老板姓名
2 from emp e,emp b
3 where e.mgr=b.empno;
員工姓名 老板姓名
---------- ----------
FORD JONES
SCOTT JONES
JAMES BLAKE
TURNER BLAKE
MARTIN BLAKE
WARD BLAKE
ALLEN BLAKE
MILLER CLARK
ADAMS SCOTT
CLARK KING
BLAKE KING
SQL> select count(*)
2 from emp e, emp b;
COUNT(*)
----------
196
自連接不適合操作大表:使用層次查詢
SQL> select level,empno,ename,mgr
2 from emp
3 connect by prior empno=mgr
4 start with mgr is null
5 order by 1;