Oracle查詢優(yōu)化改寫技巧與案例 第一章 單表查詢

進行查詢操作之前,我們先查看一下表結(jié)構(gòu)
若領(lǐng)導(dǎo)要查看員工的所有信息,這個操作很簡單,大家應(yīng)該都會用。只要用色select * 就可以返回目標表中的所有的列,查詢語句及執(zhí)行結(jié)果如下:
若想查看公司有多少銷售人員,那么,我們在查詢數(shù)據(jù)時只需加一個過濾條件就可以。職位列是job,銷售人員條件就是WHERE job='SALESMAN'
如果要查詢某一列為空的數(shù)據(jù)該怎么辦呢?比如,返回提成(comm)為空的數(shù)據(jù):
通過1.1節(jié)的查詢結(jié)果可以看到,明顯有提成為空的數(shù)據(jù),這里卻沒有查到。
問題出現(xiàn)在哪里呢?實際上,NULL是不能用“=”運算符的,要用IS NULL判斷,正確的寫法如下:
NULL不支持加、減、乘、除、大小比較、相等比較,否則只能為空;
因為NULL不支持加、減、乘、除、大小比較、相等比較,所以需要把空值改為有意義的值:
NVL只能處理單個參數(shù),如果要處理多個參數(shù),則可以使用COALESCE。
創(chuàng)建示例數(shù)據(jù):
上面示例中C1~C6各列均有空值,要求取出第一個不為空的值,如果要用NVL,則需要嵌套很多層:
而使用COALESCE就簡單得多:
函數(shù)對空值的處理方式各不一樣,有些會返回空值:
有些會返回期望的結(jié)果:
而在DECODE中還可以比較空值:
可以看到,不同的函數(shù)對NULL的支持也不一樣,所以大家遇到NULL時最好測試下結(jié)果會受什么影響,不要僅憑想象。
對于簡單的查詢,操作起來比較容易,那么復(fù)雜一點的呢?比如我們要查詢部門10中的所有員工,所有得到提成的員工,以及部門20中工資不超過2000美元的員工。
這是三個條件的組合,符合上述任一條件即可。
我們要把這三個條件整理成邏輯表達式的形式:(部門10中的員工 OR 所有得到提成的員工 OR (工資<=2000 and 部門號=20))。
注意:對于多個條件的組合,要使用括號,這樣在更改維護語句時可以不必再考慮優(yōu)先級問題,而且可以很容易地借助各種工具找到各組合條件的起止位置。
那么我們可以這樣寫:
前面我們都是取表中所有的列,但在實際的場景中,常常只需要返回部分列的數(shù)據(jù)就可以,比如只需要員工編號、員工名稱、雇用日期、工資。所以一般要明確指定查詢那些列,而不是用“*”號來代替。另外,要明確返回的列也會使語句的維護更簡單,而不必每次看到語句時都需要查看表結(jié)構(gòu)才知道返回什么數(shù)據(jù)。
不是每個人都能看懂那些簡寫的字母是什么意思,所以應(yīng)該給列取個別名。你可以如下面所示在as后面跟別名;也可以不要as,直接在列名后面跟別名即可。
看看下面這個報表數(shù)據(jù),就會一目了然。
寫報表時,經(jīng)常會加上各種條件,而直接在條件中使用別名比列名(如B01,B02,B03)要清晰得多,引用別名時千萬別忘記了嵌套一層,因為這個別名是在SELECT之后才有效的。
如下示例是尋找那些拖累了國家GDP后退的人:
否則會提示:
若有人不喜歡看表格式的數(shù)據(jù),希望返回的數(shù)據(jù)都像"CLARK的工作是MANAGER"這樣的顯示。我們可以用字符串連接符"||"來吧各列拼在一起。
當然,拼接列對我們來說還有其他意義。看看下面的例子。
沒錯,這就是用SQL來生成SQL。當你有大量類似的SQL需要生成時,可以先寫一個語句,然后進行修改,直接用基礎(chǔ)數(shù)據(jù)或數(shù)據(jù)字典來批量生成。不過不要去執(zhí)行這個例子生成的SQL,否則會丟失數(shù)據(jù)。
提示:作者的博客中就有一個拼接列處理問題的例子"通過對照表快速建view",網(wǎng)址為http://blog.csdn.net/jgmydsai/article/details/25893409。
有時為了更清楚地區(qū)分返回的信息,需要作如下處理。
例如,當志愿工資小于或等于2000美元時,就返回消息"過低",大于或等于4000美元時,就返回消息"過高",如果在兩者之間,就返回“OK”。
類似這種需求也許會經(jīng)常遇見,處理這樣的需求可以用CASE WHEN來判斷轉(zhuǎn)化。
這種方式還常用在報表中,比如,要按工資分檔次統(tǒng)計人數(shù):
在查詢時,并不要求每次都要返回所有的數(shù)據(jù),比如,進行抽查的時候會要求只返回兩條數(shù)據(jù)。
我們可以用偽劣rownum來過濾,rownum一次對返回的每一條數(shù)據(jù)做一個標識。
如果直接用rownum = 2來查詢會出現(xiàn)什么情況?
因為rownum是依次對數(shù)據(jù)做標識的,就像上學(xué)時依據(jù)考分排名一樣,需要有第一名,后面才會有第二名。所以,要先把所有的數(shù)據(jù)取出來,才能確認第二名。
正確地取第二行數(shù)據(jù)的查詢應(yīng)該像下面這樣,先生成序號: