Oracle查询优化-01单表查询
- 概述
- 1 查詢表中所有的行與列
- 2 從表中檢索部分行
- 3 查找空值
- 4 將空值轉(zhuǎn)換為實際值
- 5 查找滿足多個條件的行
- 6 從表中檢索部分列
- 7 為列取有意義的名稱
- 8 在 WHERE 子句中引用取別名的列
- 9 拼接列
- 使用字符串連接符 用SQL生成SQL
- 10 在 SELECT 語句中使用條件邏輯 case when
- 11 限制返回的行數(shù)
- 12 從表中隨機返回 n 條記錄
- 13 模糊查詢
- 查出vname中包含的
- 查出vname中包含_BCE的
概述
目標表:
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>1.1 查詢表中所有的行與列
select * from emp;1.2 從表中檢索部分行
只需要加過濾條件即可
select * from emp a where a.ename='ALLEN';1.3 查找空值
null值 “=”判斷,需用is null判斷
select * from emp where comm is null;null值也不支持 加減乘除 大小比較 相等比較,否則只能為空。
對于其他函數(shù),在使用時最好測試一下null值時會返回什么結(jié)果。
1.4 將空值轉(zhuǎn)換為實際值
select coalesce(comm,0) from emp;有人會問,為什么不是nvl 而是 coalesce呢? 因為coalesce更好用。
看下面這個例子,返回多個值中第一個不為空的值。
CREATE OR REPLACE VIEW xgj AS SELECT NULL AS C1, NULL AS C2, 1 AS C3, NULL AS C4, 2 AS C5, NULL AS C6 FROM DUAL UNION ALL SELECT NULL AS C1, NULL AS C2, NULL AS C3, 3 AS C4, NULL AS C5, 2 AS C6 FROM DUAL; SQL> select * from xgj;C1 C2 C3 C4 C5 C6 -- -- ---------- ---------- ---------- ----------1 2 3 2SQL> SQL> select coalesce(c1,c2,c3,c4,c5,c6) from xgj;COALESCE(C1,C2,C3,C4,C5,C6) --------------------------- 1 3SQL>可以看到對于nvl來說,coalesce支持多個參數(shù),能很方便的返回第一個不為空的值,如果上面的語句改用nvl.則需要套用很多層
SQL> select nvl(nvl(nvl(nvl(nvl(c1, c2), c3), c4), c5), c6) from xgj;NVL(NVL(NVL(NVL(NVL(C1,C2),C3) ---------------------------------------- 1 3SQL>1.5 查找滿足多個條件的行
對于簡單的查詢,操作起來比較簡單,那么復(fù)雜一點兒的呢? 比如 ,查詢部門號10中的所有員工、所有得到提成的員工、以及部門20中工資不超過2000的員工。
這是三個條件的組合,符合上述任一一條即可。
注意:對于多個條件的組合,要使用括號,這樣在更改維護語句時可以不必再考慮優(yōu)先級問題,而且可以很容易的借助龔總工具找到組合條件的起始位置
select *from emp ewhere (e.deptno = 10 or e.comm is not null or (e.sal > 2000 and e.deptno = 20));1.6 從表中檢索部分列
select empno ,ename from emp a ;1.7 為列取有意義的名稱
不是每個人都能看懂那些簡寫字母是什么意思,所有在必要的時候應(yīng)該給列取個別名。
在as 后面跟別名,也可以不要as 直接在列名后跟別名。
SQL> select empno as 工號 ,ename 姓名 from emp a ;工號 姓名 ----- ----------7369 SMITH...........1.8 在 WHERE 子句中引用取別名的列
寫報表時,經(jīng)常會加上各種條件, 引用別名時,千萬別忘了嵌套一層,因為這個別名是在select之后才有效的.
比如:
SQL> select *2 from (select ename 姓名, sal as 工資 from emp a)3 where 工資 < 1000;姓名 工資 ---------- --------- SMITH 800.00 JAMES 950.00SQL>如果不嵌套,提示 標識符無效
SQL> select ename 姓名, sal as 工資 from emp a where 工資 < 1000;select ename 姓名, sal as 工資 from emp a where 工資 < 1000ORA-00904: "工資": invalid identifierSQL>1.9 拼接列 “||”
我們可以使用字符串連接符“||”將各個列拼在一起。
SQL> select ename || '的工資是' || sal as msg from emp ;MSG -------------------------------------------------------------- SMITH的工資是800 ALLEN的工資是1600 ......當然了對于拼接列,我們還可以如下使用
使用字符串連接符 用SQL生成SQL
select 'truncate table ' || owner || '.' || table_name || '; ' from all_tables ;1.10 在 SELECT 語句中使用條件邏輯 case when
SQL> select ename,job,casewhen job = 'ANALYST' then'分析員'when job = 'CLERK' then'服務(wù)員'when job = 'MANAGER' then'經(jīng)理'when job = 'PRESIDENT' then'主席'else'其他'end as 職位from emp;ENAME JOB 職位 ---------- --------- --------- SMITH CLERK 服務(wù)員 ALLEN SALESMAN 其他 WARD SALESMAN 其他 JONES MANAGER 經(jīng)理 MARTIN SALESMAN 其他 BLAKE MANAGER 經(jīng)理 CLARK MANAGER 經(jīng)理 SCOTT ANALYST 分析員 KING PRESIDENT 主席 TURNER SALESMAN 其他 ADAMS CLERK 服務(wù)員 JAMES CLERK 服務(wù)員 FORD ANALYST 分析員 MILLER CLERK 服務(wù)員14 rows selectedSQL>1.11 限制返回的行數(shù)
在查詢時,并不要求返回所有的數(shù)據(jù),比如進行抽查的時候會要求只返回兩條數(shù)據(jù)。
我們可以使用偽列rownum來過濾,rownum依次對返回的每一條數(shù)據(jù)做一個標識 。
SQL> select * from emp where rownum <=2 ;EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ---------- --------- ----- ----------- --------- --------- ------7369 SMITH CLERK 7902 1980-12-17 800.00 207499 ALLEN SALESMAN 7698 1981-02-20 1600.00 300.00 30SQL>如果只想取第二條呢?
SQL> select * from emp where rownum =2 ;EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ---------- --------- ----- ----------- --------- --------- ------SQL>顯然是不行的。 因為rownum是依次對數(shù)據(jù)做標識的,所以要先把所有的數(shù)據(jù)取出來,才能確認第二條記錄。
我們可以這樣
SQL> select * from (select rownum as rn,a.* from emp a where rownum <=2) where rn=2;RN EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ----- ---------- --------- ----- ----------- --------- --------- ------2 7499 ALLEN SALESMAN 7698 1981-02-20 1600.00 300.00 30SQL>1.12 從表中隨機返回 n 條記錄
我們可以先用dbms_random來對數(shù)據(jù)先進行數(shù)據(jù)排序,然后取其中三列。
select *from (select ename, job, sal, comm from emp order by dbms_random.value())where rownum <= 3;1.13 模糊查詢
數(shù)據(jù):
CREATE OR REPLACE VIEW xgj AS SELECT 'ABCEDF' AS vname FROM dual UNION ALL SELECT '_BCEFG' AS vname FROM dual UNION ALL SELECT '_BCEDF' AS vname FROM dual UNION ALL SELECT '_\BCEDF' AS vname FROM dual UNION ALL SELECT 'XYCEG' AS vname FROM dual; SQL> select * from xgj;VNAME ------- ABCEDF _BCEFG _BCEDF _\BCEDF XYCEGSQL>查出vname中包含CED的
SQL> select * from xgj where vname like '%CED%';VNAME ------- ABCEDF _BCEDF _\BCEDFSQL>查出vname中包含“_BCE”的
SQL> select * from xgj where vname like '_BCE%';VNAME ------- ABCEDF _BCEFG _BCEDFSQL>發(fā)現(xiàn)突然多了一個 ABCDEF , 因為在like子句中有個兩個通配符
- % 代替一個或者多個字符
- _ 代替一個字符
在這里“_”被當成通配符了,那怎么辦呢? 我們可以使用轉(zhuǎn)義字符。
SQL> select * from xgj where vname like '\_BCE%' escape '\';VNAME ------- _BCEFG _BCEDFSQL>ESCAPE 把‘\’標識作為轉(zhuǎn)義字符, 而 ‘\’把‘_’轉(zhuǎn)義為字符,而非其愿義(通配符)。
我們注意到我們的數(shù)據(jù)中 有 一列的值為 _\BCEDF ,那么加了ESCAPE ‘\’ 后怎么返回呢?
SQL> select * from xgj where vname like '_\BCE%' escape '\';select * from xgj where vname like '_\BCE%' escape '\'ORA-01424: missing or illegal character following the escape character雙寫轉(zhuǎn)義字符即可
SQL> select * from xgj where vname like '_\\BCE%' escape '\';VNAME ------- _\BCEDFSQL>對于字符串中包含’%’ 的也一樣的方式處理
總結(jié)
以上是生活随笔為你收集整理的Oracle查询优化-01单表查询的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux 磁盘I/O读写速度检测
- 下一篇: Oracle查询优化-02给查询结果排序