Oracle查詢優(yōu)化改寫技巧與案例 第二章 給查詢結(jié)果排序

2.1以指定的次序返回查詢結(jié)果
實(shí)際提取數(shù)據(jù)或生成報(bào)表時(shí),一般都要根據(jù)一定的順序查看,比如,想查看單位所雇員工的信息:
這種語(yǔ)句很多人都會(huì)寫,但除了"ORDER BY hiredate ASC"這種寫法,還可以寫成"ORDER BY 3 ASC",意思是按第三列排序。
當(dāng)取值不定時(shí),用這種方法就很方便,比如,有時(shí)取sal,有時(shí)要取comm來(lái)顯示:
對(duì)于這種需求,如果在order by 后使用列名,就需要注意前后保持一致,否則會(huì)給開發(fā)軟件帶來(lái)“小麻煩”。比如,開發(fā)初期的語(yǔ)句如下:
后來(lái)要求增加empno的顯示,而我們經(jīng)常要按第一列排序,于是需要改為:
如果語(yǔ)句比較復(fù)雜,會(huì)經(jīng)常忘記更改后面的order by,但使用“order by 3”這種方式就沒(méi)有問(wèn)題。
需要注意的是,用數(shù)據(jù)來(lái)替代列位置只能用于order by 子句中,其它地方都不能用。
2.2按多個(gè)字段排序
如果按多列排序且有升有降怎么辦?例如,按部門編號(hào)升序,并按工資降序排列。
排序時(shí)有兩個(gè)關(guān)鍵字:ASC表示升序、DESC表示降序。
所以我們?cè)趏rder by后加兩列,分別標(biāo)明ASC、DESC。
下面用圖的形式進(jìn)行介紹,如下圖所示,按多列排序時(shí),若前面的列有重復(fù)值(如deptno=10有3行數(shù)據(jù)),后面的排序才有用。相當(dāng)于是通過(guò)前面的列把數(shù)據(jù)分成了幾組,每組的數(shù)據(jù)在按后面的列進(jìn)行排序。

2.3按子串排序
有一種速查法就是按顧客電話號(hào)碼尾號(hào)的順序記錄,這樣在查找的時(shí)候就可以快速縮小查詢范圍,增強(qiáng)顧客的認(rèn)可度。如果要按這種方法排序,應(yīng)該怎樣做呢?通過(guò)函數(shù)取出后面幾位所需的信息即可。
按子串排序?qū)嶋H就是增加一個(gè)計(jì)算列,然后用這個(gè)計(jì)算列來(lái)排序。
2.4從表中隨機(jī)返回n條記錄
為了防止做假,像前面那樣抽查數(shù)據(jù)還不行,還需要隨機(jī)抽查。
我們可以先用dbms_random來(lái)對(duì)數(shù)據(jù)進(jìn)行隨機(jī)排序,然后取其中三行。
有人會(huì)問(wèn):為什么要嵌套一層呢?直接這樣用多好。
你可以運(yùn)行一下看,為了便于觀察,我們對(duì)得到的結(jié)果進(jìn)行排序,運(yùn)行下面的語(yǔ)句就可以。
多運(yùn)行幾次,會(huì)發(fā)現(xiàn)每次得到的數(shù)據(jù)都一樣,而不是隨機(jī)的。
為了便于解釋,我們先對(duì)上面的語(yǔ)句進(jìn)行等價(jià)改寫:
查詢語(yǔ)句中這幾處的執(zhí)行順序?yàn)椋?/p>
SELECT
ROWNUM
ORDERBY
也就是說(shuō),要先取出數(shù)據(jù),然后生成序號(hào),最后才是排序。
我們可以通過(guò)子查詢把排序前后的序號(hào)分別取出來(lái)對(duì)比。
同樣,你可以多運(yùn)行幾次,看是不是與剛才描述的一致。
因此,正確的寫法是:先隨機(jī)排序,再去數(shù)據(jù)。
錯(cuò)誤的寫法是:先取數(shù)據(jù),在隨機(jī)排序
2.5TRANSLATE
語(yǔ)法格式:TRANSLATE(expr,from_string,to_string)
示例如下:
from_string 與to_string以字符為單位,對(duì)應(yīng)字符一一替換。

如果to_string為空,則返回空值。
如果to_string對(duì)應(yīng)的位置沒(méi)有字符,則from_string中列出的字符將會(huì)被消掉。

2.6按數(shù)字和字母混合字符串中的字母排序
首先創(chuàng)建VIEW如下:
這個(gè)需求救難一點(diǎn)了,看到里面的字母(也就是原來(lái)的列ename)了嗎?要求按其中的字母(列ename)排序。
那么就要先取出其中的字母才行,我們可以用translate的替換功能,把數(shù)字與空格都替換為空:
2.7處理排序空值
Oracle默認(rèn)升序默認(rèn)空值在后,降序空值在前。
如果想要更改空值順序,則可以用關(guān)鍵字NULLS FIRST和NULL LAST。
2.8根據(jù)條件取不同列中的值來(lái)排序
有時(shí)排序的要求會(huì)比較復(fù)雜,比如,領(lǐng)導(dǎo)對(duì)工資在1000到2000元之間的員工更感興趣,于是要求工資在這個(gè)范圍的員工要排在前面,以便優(yōu)先查看。
對(duì)于這種需求,我們可以在查詢中新生成一列,用多列排序的方法處理:

可以看到,950與2850都排在了后面,也可以不顯示級(jí)別,直接把case when放在order by中:
