需求:前端
在profit(收益)表中包含一列 ‘rate(費率)’爲百分比,數據類型爲varchar,插入的數據爲百分數(即xx.xx%)。要求按照百分比的大小排序,數據庫爲oracle。
分析:sql
以升序爲例,該需求中rate字段爲varcahr類型,所以直接排序會出現「1%->10%->11%->2%->3%」的狀況,顯然不是咱們想要的結果。 因此咱們須要對該列數據查詢時進行數據類型轉換,轉換成 number 類型;在oracle中提供了兩個將字符串類型轉換爲數字類型的方式: 一、TO_NUMBER(COLUMN) 將某一列轉換爲數字類型。 二、CAST(COLUMN AS NUMBER(10,2)) 將某一列轉換爲其餘類型,此處爲數字,只要條件知足能夠轉換爲其餘任意類型。 不過,通過測試,這樣直接進行數據類型轉換後排序,是不可行的,會報錯:該列不是有效的數字,什麼緣由呢?是由於,rate列中存在「%」,「xx%」不是有效的數字,不能直接轉換爲number類型。 此時,咱們只須要將末尾的「%」去除就獲得能夠轉換爲number類型的數字,也就咱們要截取字符串,將「%」前面的數據截取出來。而在oracle中提供了 substr 方法用來截取字符串: 語法: substr( string, start_position, [ length ] ) 其中string爲字符串,start_position爲起始位置,length爲截取長度; 其中start_position爲負數的時起始位置從字符串末尾開始算起。 length可省略,而length省略時返回start_position位置後面的全部字符 看到這裏,就發現 substr 方法中只能日後截取,而不能從後往前截取。另外,咱們須要的是「%」前面的全部字符的,但其長度是未知的,所以就用到了另一個方法instr,instr方法會返回指定字符出現的位置。即指定字符查找: 語法: instr(string1,string2[,start_position[,nth_appearence]]) string1:要在此字符串中查找。 string2:要在string1中查找的字符串。 start_position:從string1開始查找的位置。可選,默認爲1,正數時,從左到右檢索,負數時,從右到左檢索。(此處與substr相同,即爲負的時候只是起始位置從右開始算) nth_appearence:查找第幾回出現string2。可選,默認爲1,不能爲負。 這樣,咱們可使用instr查找「%」出現的位置,也就是該列數據的最後一個字符位置索引,用索引減1,獲得該列數據去除百分號後的字符長度,也就是咱們須要截取字符串的長度,截取的字符串爲:substr(rate, 0,instr(rate,'%')-1),而後將它轉化爲number類型,並排序就OK了! 最後咱們獲得sql語句: select * from profit order by CAST(substr(rate , 0,instr(rate ,'%')-1) AS number(10,2))或 select * from profit order by to_number(substr(rate , 0,instr(rate ,'%')-1))
總結:數據庫
實際開發中這樣的狀況比較少,由於「%」這個東西,能夠直接在前端加的,數據庫裏面只須要存儲number類型的數據就可了。但也存在其餘相似的狀況,例如:某公司的員工編號:序號+M,序號+MX。。。相似的狀況仍是有的。 另外,若是字母在前面那麼的話更爲簡單,由於只須要從字母后一位開始,截取字母后面的全部就能夠直接轉換類型排序了。