[SQL] 容易忽略的SubQuery意外

  • 12105
  • 0
  • 2011-11-11

一般我們在下資料庫查詢語法時,不外乎就是select再加上join或是採用子查詢(SubQuery),

通常在寫的時候大部份情況下,我們都會很容易寫一寫然後測試run一下,嗯......資料出的來.....資料查出來也正確

,然後就收工完成( 降龍十八掌展示完畢...收功..... )

但不幸的是事情往往總發生在收工(收功)之後......

        一般我們在下資料庫查詢語法時,不外乎就是select再加上join或是採用子查詢(SubQuery),

通常在寫的時候大部份情況下,我們都會很容易寫一寫然後測試run一下,嗯......資料出的來.....資料查出來也正確

,然後就收工完成( 降龍十八掌展示完畢...收功..... )

       可是很不幸的,往往那麼累積幾千幾萬筆資料後,一些意外可能就發生了,

例如查詢效能不好或是資料查出來好像有某幾筆資料不太對或是原本好好的語法怎麼突然間有錯誤了

而這些意外說到底可能都是在開發時沒有考慮進來而發生的,最常見的應該該算效能不好的問題,

再來就屬語法上考慮不全的問題了,

        舉例來說:當你想查員工最高學歷,可能會用以下的語法

 

Select 員工編號 , 姓名

,( select  代碼檔.學歷等級名稱
    from 員工學歷檔  
    left join 代碼檔 on員工學歷檔.學歷等級id =代碼檔.id  
    where 員工學歷檔.eid = 員工檔.id  
     and 學歷code = (select max(code) from代碼檔 where ctype=’學歷等  級’))   學歷
from員工檔

 

這個語法一般情況下run起來,應該都ok的,但是當遇到雙學位的情況呢?


例如員工甲有雙碩士學位,那麼學歷檔也建了二筆碩士學位的資料,對映到代碼就會有二筆學歷等級相同(碩士)

,而這個SQL採用子查詢方式去取後最高學歷資料,偏偏子查詢只能做單筆回傳

( 你可以想想看若是子查詢放在SELECT裡,又要它能回傳多資料,那它該如何呈現資料?)

所以這個查詢就掛了,也因為這樣才會發生了某些時候查詢不能跑,某些時候查詢又是正常的,

因為只要所查出來的資料沒有雙學位的案例,當然SQL也不會錯,就會正常

          

在這個案例裡有幾個是可以討論的

(1)     採用子查詢時,要特別注意資料的回傳是否可能會有多筆的情況

(2)     子查詢v.s join,就效能上來看,沒有誰一定比較好,只能說在大部份情況下join的效能會來的較好,但也有部份情況下子查詢效能是高於join的,所以要視case而定

(3)     在寫查詢SQL時要多考慮一些可能存在的資料,不然意外情況應該會常發生的

(4)     以這個例子來說,想找最高學歷的條件恐怕要再加上畢業年月等日期的或是其它條件來判斷,會比較嚴謹一點
 

 

若本文對您有所幫助,歡迎轉貼,但請在加註【轉貼】及來源出處,並在附上本篇的超連結,感恩您的配合囉。

By No.18