Oracle查詢優化學習
一、單表查詢
SQL> desc emp; Name Type Nullable Default Comments -------- ------------ -------- ------- -------- EMPNO NUMBER(4) ENAME VARCHAR2(10) Y JOB VARCHAR2(9) Y MGR NUMBER(4) Y HIREDATE DATE Y SAL NUMBER(7,2) Y COMM NUMBER(7,2) Y DEPTNO NUMBER(2) Y
1.查詢表中所有行與列
如:檢視員工所有資訊
SQL> select * from emp; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ---------- --------- ----- ----------- --------- --------- ------ 7369 SMITH CLERK 7902 1980/12/17 800.00 20 7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30 7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30 7566 JONES MANAGER 7839 1981/4/2 2975.00 20 7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30 7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30 7782 CLARK MANAGER 7839 1981/6/9 2450.00 10 7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20 7839 KING PRESIDENT 1981/11/17 5000.00 10 7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30 7876 ADAMS CLERK 7788 1987/5/23 1100.00 20 7900 JAMES CLERK 7698 1981/12/3 950.00 30 7902 FORD ANALYST 7566 1981/12/3 3000.00 20 7934 MILLER CLERK 7782 1982/1/23 1300.00 10 14 rows selected
2.從表中檢索部分行
如:檢視工所有多少銷售人員
SQL> select * from emp where job = 'SALESMAN'; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ---------- --------- ----- ----------- --------- --------- ------ 7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30 7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30 7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30 7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
3.查詢空值
SQL> select * from emp where comm is null;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 800.00 20
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7876 ADAMS CLERK 7788 1987/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 950.00 30
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
null不能用“=”運算子,要用is null判斷
null不支援加、減、乘、除、大小比較、相等比較,否則只能為空
4.將空值轉化為實際值
SQL> select ename ,coalesce(comm,0) from emp;
ENAME COALESCE(COMM,0)
---------- ----------------
SMITH 0
ALLEN 300
WARD 500
JONES 0
MARTIN 1400
BLAKE 0
CLARK 0
SCOTT 0
KING 0
TURNER 0
ADAMS 0
JAMES 0
FORD 0
MILLER 0
14 rows selected
5.返回多個值中第一個不為空的值
SQL> create or replace view v as
2 select null as c1, null as c2,1 as c3 , null as c4 , 2 as c5, null as c6 from dual
3 union all
4 select null as c1 , null as c2 , null as c4,3 as c4, null as c5 , 2 as c6 from dual;
View created
SQL> select coalesce(C1,C2,C3,C4,C5,C6) as c from v;
C
----------
1
3
6.查詢滿足多個條件的行
如:查詢部門10中所有員工、所有得到提成的員工,以及部門20中工資不超過2000美元的員工
SQL> select * from emp where (deptno=10 or comm is not null or(sal <= 2000 and deptno = 20));
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 ADAMS CLERK 7788 1987/5/23 1100.00 20
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
9 rows selected
7.從表中檢索部分列SQL> select empno,ename,hiredate,sal from emp where deptno=10;
EMPNO ENAME HIREDATE SAL
----- ---------- ----------- ---------
7782 CLARK 1981/6/9 2450.00
7839 KING 1981/11/17 5000.00
7934 MILLER 1982/1/23 1300.00
8.為列取有意義名字SQL> select ename as 姓名,deptno as 部門編號,sal as 工資,comm as 提成 from emp;
姓名 部門編號 工資 提成
---------- ---- --------- ---------
SMITH 20 800.00
ALLEN 30 1600.00 300.00
WARD 30 1250.00 500.00
JONES 20 2975.00
MARTIN 30 1250.00 1400.00
BLAKE 30 2850.00
CLARK 10 2450.00
SCOTT 20 3000.00
KING 10 5000.00
TURNER 30 1500.00 0.00
ADAMS 20 1100.00
JAMES 30 950.00
FORD 20 3000.00
MILLER 10 1300.00
14 rows selected
9.在where條件中引用取別名的列SQL> select * from (select sal as 工資,comm as 提成 from emp) x where 工資<1000;
工資 提成
--------- ---------
800.00
950.00
注意:引用別名時千萬別忘了巢狀一層,因為這個別名是在select之後才生效的。10.拼接列
SQL> select ename || '的工作是'||job as msg from emp where deptno = 10;
MSG
-------------------------------
CLARK的工作是MANAGER
KING的工作是PRESIDENT
MILLER的工作是CLERK
11.拼接列高階用法SQL> select 'TRANCATE TABLE' || owner || '.'|| table_name || ';' as 清空表 from all_tables where owner = 'SCOTT';
清空表
----------------------------------------------------------------------------
TRANCATE TABLESCOTT.DEPT;
TRANCATE TABLESCOTT.EMP;
TRANCATE TABLESCOTT.BONUS;
TRANCATE TABLESCOTT.SALGRADE;
12.在select語句中使用條件邏輯如:當職員工資小於或等於2000時候,就返回訊息'太低',大於或等於4000時就返回'過高',如果在這兩者之間就返回'OK';
SQL> select ename,
2 sal,
3 case
4 when sal < 2000 then
5 '過低'
6 when sal >= 4000 then
7 '過高'
8 else
9 'ok'
10 end as status
11 from emp
12 where deptno = 10;
ENAME SAL STATUS
---------- --------- ------
CLARK 2450.00 ok
KING 5000.00 過高
MILLER 1300.00 過低
13.按照工資分檔次統計人數SQL> select 檔次,count(*) as 人數
2 from (
3 select (
4 case
5 when sal <=1000 then '0000-1000'
6 when sal <=2000 then '2000-3000'
7 when sal <=3000 then '3000-4000'
8 when sal <=4000 then '4000-5000'
9 end) as 檔次,
10 ename,
11 sal
12 from emp)
13 group by 檔次
14 order by 1;
檔次 人數
--------- ----------
0000-1000 2
2000-3000 6
3000-4000 5
1
14.限制返回行數rownum是一次對資料做標識的,就像上學時依據考分排名一樣,需要有第一名,後面才會有第二名。
如:獲取第二行資料
SQL> select * from (select rownum as sn , emp.* from emp where rownum <=2) where sn = 2;
SN EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ----- ---------- --------- ----- ----------- --------- --------- ------
2 7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
如:獲取所有員工資訊,按照員工編號降序
SQL> select * from emp order by empno desc;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
7900 JAMES CLERK 7698 1981/12/3 950.00 30
7876 ADAMS CLERK 7788 1987/5/23 1100.00 20
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7839 KING PRESIDENT 1981/11/17 5000.00 10
7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7369 SMITH CLERK 7902 1980/12/17 800.00 20
14 rows selected
如:獲取前兩條資料
SQL> select * from (select * from emp order by empno desc) where rownum <=2;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7934 MILLER CLERK 7782 1982/1/23 1300.00 10
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
15.從表中隨機返回n條記錄SQL> select empno ,ename from (select empno,ename from emp order by dbms_random.value()) where rownum <=3;
EMPNO ENAME
----- ----------
7654 MARTIN
7839 KING
7844 TURNER
16.模糊查詢
SQL> create or replace view v as
2 select 'ABCEDF' as vname from dual
3 union all
4 select '_BCEFG' as vname from dual
5 union all
6 select '_BCEDF' as vname from dual
7 union all
8 select '_\BCEDF' as vname from dual
9 union all
10 select 'XYCEG' as vname from dual;
View created
如:查出vname中包含字串"CED"的資料
SQL> select * from v where vname like '%CED%';
VNAME
-------
ABCEDF
_BCEDF
_\BCEDF
如:查出vname中包含字串“_BCE"的資料
SQL> select * from v where vname like '_BCE%';
VNAME
-------
ABCEDF
_BCEFG
_BCEDF
發現"_"被當作萬用字元了,需要escape
如:查出vname中包含字串“_BCE"的資料
SQL> select * from v where vname like '\_BCE%' escape '\';
VNAME
-------
_BCEFG
_BCEDF
-------------------1.以指定次序返回查詢結果
如:檢視單位僱員的資訊
SQL> select empno , ename ,hiredate from emp where deptno = 10 order by hiredate asc;
EMPNO ENAME HIREDATE
----- ---------- -----------
7782 CLARK 1981/6/9
7839 KING 1981/11/17
7934 MILLER 1982/1/23
SQL> select empno , ename ,hiredate from emp where deptno = 10 order by 3 asc;
EMPNO ENAME HIREDATE
----- ---------- -----------
7782 CLARK 1981/6/9
7839 KING 1981/11/17
7934 MILLER 1982/1/23
2.按多個欄位排序如:按部門編號升序,按工資降序排列
SQL> select empno , deptno ,sal ,ename ,job from emp order by 2 asc , 3 desc;
EMPNO DEPTNO SAL ENAME JOB
----- ------ --------- ---------- ---------
7839 10 5000.00 KING PRESIDENT
7782 10 2450.00 CLARK MANAGER
7934 10 1300.00 MILLER CLERK
7788 20 3000.00 SCOTT ANALYST
7902 20 3000.00 FORD ANALYST
7566 20 2975.00 JONES MANAGER
7876 20 1100.00 ADAMS CLERK
7369 20 800.00 SMITH CLERK
7698 30 2850.00 BLAKE MANAGER
7499 30 1600.00 ALLEN SALESMAN
7844 30 1500.00 TURNER SALESMAN
7654 30 1250.00 MARTIN SALESMAN
7521 30 1250.00 WARD SALESMAN
7900 30 950.00 JAMES CLERK
多列排序時,若前面的列有重複值(如deptno=10有3行資料) 後面的排序才有用3.按子串排序
如:按顧客電話尾號順序排序
SQL> select last_name as 名稱,
2 phone_number as 號碼,
3 salary as 工資,
4 substr(phone_number,-4) as 尾號
5 from hr.employees
6 where rownum <=5
7 order by 4;
名稱 號碼 工資 尾號
------------------------- -------------------- ---------- ----------------
King 515.123.4567 24000.00 4567
Hunold 590.423.4567 9000.00 4567
Kochhar 515.123.4568 17000.00 4568
Ernst 590.423.4568 6000.00 4568
De Haan 515.123.4569 17000.00 4569
a.Sql執行順序
1 (8)SELECT (9) DISTINCT (11) <TOP_specification> <select_list>
2 (1) FROM <left_table>
3 (3) <join_type> JOIN <right_table>
4 (2) ON <join_condition>
5 (4) WHERE <where_condition>
6 (5) GROUP BY <group_by_list>
7 (6) WITH {CUBE | ROLLUP}
8 (7) HAVING <having_condition>
9 (10) ORDER BY <order_by_list>
b.如果對排序之後資料取前幾條資料,一定要在外面包一層查詢。4.TRANSLATE
SQL> select translate('ab 你好 bcadefg','abcdefg','1234567') as new_str from dual;
NEW_STR
-----------------
12 你好 2314567
5.按數字和字母混合字串中的字母排序
6.處理排序空值
SQL> select ename , sal ,comm , nvl(comm , -1) order_col from emp order by 4;
ENAME SAL COMM ORDER_COL
---------- --------- --------- ----------
SMITH 800.00 -1
CLARK 2450.00 -1
FORD 3000.00 -1
JAMES 950.00 -1
ADAMS 1100.00 -1
JONES 2975.00 -1
BLAKE 2850.00 -1
MILLER 1300.00 -1
SCOTT 3000.00 -1
KING 5000.00 -1
TURNER 1500.00 0.00 0
ALLEN 1600.00 300.00 300
WARD 1250.00 500.00 500
MARTIN 1250.00 1400.00 1400
14 rows selected
oracle預設排序空值在後面,如果想把空值顯示在前面怎麼辦如:空值在前面
SQL> select ename , sal, comm from emp order by 3 nulls first;
ENAME SAL COMM
---------- --------- ---------
SMITH 800.00
CLARK 2450.00
FORD 3000.00
JAMES 950.00
ADAMS 1100.00
JONES 2975.00
BLAKE 2850.00
MILLER 1300.00
SCOTT 3000.00
KING 5000.00
TURNER 1500.00 0.00
ALLEN 1600.00 300.00
WARD 1250.00 500.00
MARTIN 1250.00 1400.00
14 rows selected
如:空值在後面SQL> select ename , sal ,comm from emp order by 3 nulls last;
ENAME SAL COMM
---------- --------- ---------
TURNER 1500.00 0.00
ALLEN 1600.00 300.00
WARD 1250.00 500.00
MARTIN 1250.00 1400.00
SCOTT 3000.00
KING 5000.00
ADAMS 1100.00
JAMES 950.00
FORD 3000.00
MILLER 1300.00
BLAKE 2850.00
JONES 2975.00
SMITH 800.00
CLARK 2450.00
7.根據條件取不同列中的值排序
如:領導對工資在1000到2000元工資的員工很感興趣,於是要求這批人排在前面
SQL> select ename as 編碼, 2 ename as 姓名, 3 case when sal >=1000 and sal<2000 then 1 else 2 end as 級別, 4 sal as 工資 5 from emp 6 where deptno = 30 7 order by 3,4 8 ; 編碼 姓名 級別 工資 ---------- ---------- ---------- --------- MARTIN MARTIN 1 1250.00 WARD WARD 1 1250.00 TURNER TURNER 1 1500.00 ALLEN ALLEN 1 1600.00 JAMES JAMES 2 950.00 BLAKE BLAKE 2 2850.00 6 rows selected或不顯示級別
SQL> select empno as 編碼,
2 ename as 姓名,
3 sal as 工資
4 from emp
5 where deptno = 30
6 order by case when sal >=1000 and sal <2000 then 1 else 2 end , 3;
編碼 姓名 工資
----- ---------- ---------
7654 MARTIN 1250.00
7521 WARD 1250.00
7844 TURNER 1500.00
7499 ALLEN 1600.00
7900 JAMES 950.00
7698 BLAKE 2850.00
6 rows selected
------------------------------------------------------------------1.union all 與空字串
SQL> select empno as 編碼, ename as 名稱, nvl(mgr, deptno) as 上級編碼
2 from emp
3 where empno = 7788
4 union all
5 select deptno as 編碼, dname as 名稱, null as 上級編碼
6 from dept
7 where deptno = 10;
編碼 名稱 上級編碼
---------- -------------- ----------
7788 SCOTT 7566
10 ACCOUNTING
當其中一個數據集不夠時候,可以用null來填充該列的值''空字串本身是varchar2型別,null可以是任何型別
2.union與or
SQL> create index idx_emp_ename on emp(ename);
Index created
SQL> create index idx_emp_empno on emp(ename);
create index idx_emp_empno on emp(ename)
ORA-01408: 此列列表已索引
如:查詢員工編號為7788或者名字為SCOTT的員工
SQL> select empno , ename from emp where empno = 7788 or ename = 'SCOTT';
EMPNO ENAME
----- ----------
7788 SCOTT
執行計劃如下:
Plan Hash Value : 1272340143
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 20 | 3 | 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID | EMP | 2 | 20 | 3 | 00:00:01 |
| 2 | BITMAP CONVERSION TO ROWIDS | | | | | |
| 3 | BITMAP OR | | | | | |
| 4 | BITMAP CONVERSION FROM ROWIDS | | | | | |
| * 5 | INDEX RANGE SCAN | PK_EMP | | | 0 | 00:00:01 |
| 6 | BITMAP CONVERSION FROM ROWIDS | | | | | |
| * 7 | INDEX RANGE SCAN | IDX_EMP_ENAME | | | 1 | 00:00:01 |
---------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 5 - access("EMPNO"=7788)
* 7 - access("ENAME"='SCOTT')
or一般改寫為union,去掉重複資料
SQL> select empno, ename from emp where empno = 7788
2 union
3 select empno , ename from emp where ename = 'SCOTT';
EMPNO ENAME
----- ----------
7788 SCOTT
執行計劃如下
Plan Hash Value : 4119156321
------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 20 | 5 | 00:00:01 |
| 1 | SORT UNIQUE | | 2 | 20 | 5 | 00:00:01 |
| 2 | UNION-ALL | | | | | |
| 3 | TABLE ACCESS BY INDEX ROWID | EMP | 1 | 10 | 1 | 00:00:01 |
| * 4 | INDEX UNIQUE SCAN | PK_EMP | 1 | | 0 | 00:00:01 |
| 5 | TABLE ACCESS BY INDEX ROWID | EMP | 1 | 10 | 2 | 00:00:01 |
| * 6 | INDEX RANGE SCAN | IDX_EMP_ENAME | 1 | | 1 | 00:00:01 |
------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 4 - access("EMPNO"=7788)
* 6 - access("ENAME"='SCOTT')
這樣兩個語句可以使用empno及ename上的索引
3.組合相關的行
如:顯示部門10的員工編碼、姓名及所在部門名稱和工作地址SQL> select e.empno,
2 e.ename ,
3 d.dname ,
4 d.loc
5 from emp e inner join dept d
6 on (e.deptno = d.deptno)
7 where e.deptno = 10;
EMPNO ENAME DNAME LOC
----- ---------- -------------- -------------
7782 CLARK ACCOUNTING NEW YORK
7839 KING ACCOUNTING NEW YORK
7934 MILLER ACCOUNTING NEW YORK
4.in、exists和inner join
SQL> create table emp2 as select ename ,job , sal , comm from emp where job = 'CLERK';
Table created
SQL> desc emp;
Name Type Nullable Default Comments
-------- ------------ -------- ------- --------
EMPNO NUMBER(4)
ENAME VARCHAR2(10) Y
JOB VARCHAR2(9) Y
MGR NUMBER(4) Y
HIREDATE DATE Y
SAL NUMBER(7,2) Y
COMM NUMBER(7,2) Y
DEPTNO NUMBER(2) Y
SQL> desc emp2
Name Type Nullable Default Comments
----- ------------ -------- ------- --------
ENAME VARCHAR2(10) Y
JOB VARCHAR2(9) Y
SAL NUMBER(7,2) Y
COMM NUMBER(7,2) Y
如:返回與表emp2(empno,job,sal)中資料相匹配的emp(empno,ename,job,sal,deptno)資訊
SQL> select empno , ename , job , sal ,deptno
2 from emp
3 where (ename , job,sal) in (select ename , job ,sal from emp2);
EMPNO ENAME JOB SAL DEPTNO
----- ---------- --------- --------- ------
7369 SMITH CLERK 800.00 20
7876 ADAMS CLERK 1100.00 20
7900 JAMES CLERK 950.00 30
7934 MILLER CLERK 1300.00 10
執行計劃
Plan Hash Value : 2994194434
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 160 | 6 | 00:00:01 |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 4 | 160 | 6 | 00:00:01 |
| 3 | SORT UNIQUE | | 4 | 60 | 3 | 00:00:01 |
| 4 | TABLE ACCESS FULL | EMP2 | 4 | 60 | 3 | 00:00:01 |
| * 5 | INDEX RANGE SCAN | IDX_EMP_ENAME | 1 | | 0 | 00:00:01 |
| * 6 | TABLE ACCESS BY INDEX ROWID | EMP | 1 | 25 | 1 | 00:00:01 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 5 - access("ENAME"="ENAME")
* 6 - filter("JOB"="JOB" AND "SAL"="SAL")
或
SQL> select empno , ename , job , sal , deptno
2 from emp a
3 where exists(select null from emp2 b where b.ename=a.ename
4 and b.job=a.job and b.sal=a.sal);
EMPNO ENAME JOB SAL DEPTNO
----- ---------- --------- --------- ------
7369 SMITH CLERK 800.00 20
7876 ADAMS CLERK 1100.00 20
7900 JAMES CLERK 950.00 30
7934 MILLER CLERK 1300.00 10
執行計劃
Plan Hash Value : 2994194434
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 160 | 6 | 00:00:01 |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 4 | 160 | 6 | 00:00:01 |
| 3 | SORT UNIQUE | | 4 | 60 | 3 | 00:00:01 |
| 4 | TABLE ACCESS FULL | EMP2 | 4 | 60 | 3 | 00:00:01 |
| * 5 | INDEX RANGE SCAN | IDX_EMP_ENAME | 1 | | 0 | 00:00:01 |
| * 6 | TABLE ACCESS BY INDEX ROWID | EMP | 1 | 25 | 1 | 00:00:01 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 5 - access("B"."ENAME"="A"."ENAME")
* 6 - filter("B"."JOB"="A"."JOB" AND "B"."SAL"="A"."SAL")
或
SQL> select a.empno,a.ename,a.job,a.sal,a.deptno from emp a
2 inner join emp2 b on (b.ename = a.ename and b.job = a.job and b.sal = a.sal);
EMPNO ENAME JOB SAL DEPTNO
----- ---------- --------- --------- ------
7369 SMITH CLERK 800.00 20
7876 ADAMS CLERK 1100.00 20
7900 JAMES CLERK 950.00 30
7934 MILLER CLERK 1300.00 10
執行計劃
Plan Hash Value : 166525280
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 160 | 7 | 00:00:01 |
| * 1 | HASH JOIN | | 4 | 160 | 7 | 00:00:01 |
| 2 | TABLE ACCESS FULL | EMP2 | 4 | 60 | 3 | 00:00:01 |
| 3 | TABLE ACCESS FULL | EMP | 14 | 350 | 3 | 00:00:01 |
----------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 1 - access("B"."ENAME"="A"."ENAME" AND "B"."JOB"="A"."JOB" AND "B"."SAL"="A"."SAL")
5.inner join 、left join 、right join和full join解析
SQL> SELECT * FROM L;
STR V
------ -
left_1 1
left_2 2
left_3 3
left_4 4
SQL> SELECT * FROM R;
STR V STATUS
------- - ----------
right_3 3 1
right_4 4 0
rifht_5 5 0
right_6 6 0
inner join 特點(只返回兩表相匹配的資料)
SQL> select l.str as left_str , r.str as right_str from l inner join r
2 on l.v=r.v
3 order by 1,2;
LEFT_STR RIGHT_STR
-------- ---------
left_3 right_3
left_4 right_4
left join特點(左表返回所有資料,右表只返回與左表相匹配資料)
SQL> select l.str as left_str, r.str as right_str
2 from l
3 left join r
4 on l.v = r.v
5 order by 1, 2
6 ;
LEFT_STR RIGHT_STR
-------- ---------
left_1
left_2
left_3 right_3
left_4 right_4
right join特點(右表返回所有資料,左表只返回與右表相匹配資料)
SQL> select l.str as left_str, r.str as right_str
2 from l
3 right join r
4 on l.v = r.v
5 order by 1, 2
6 ;
LEFT_STR RIGHT_STR
-------- ---------
left_3 right_3
left_4 right_4
rifht_5
right_6
full jon 特點(左右表均返回說有資料,但只有相匹配的資料顯示同一行,非匹配的行只顯示一個表資料)
SQL> select l.str as left_str, r.str as right_str
2 from l
3 full join r
4 on l.v = r.v
5 order by 1, 2
6 ;
LEFT_STR RIGHT_STR
-------- ---------
left_1
left_2
left_3 right_3
left_4 right_4
rifht_5
right_6
6 rows selected
6.自關聯
select worker.empno as 職工編碼,
worker.ename as 職工姓名,
worker.job as 工作,
worker.mgr as 員工表_主管編碼,
boss.empno as 主管表_主管編碼,
boss.ename as 主管表姓名
from emp worker, emp boss
where worker.mgr = boss.empno;
注意:1.這個時候表起別名會報錯