關於數據庫百分數排序(包含字符串截取,指定字符查找,類型轉換)

需求:前端

在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。。。相似的狀況仍是有的。
另外,若是字母在前面那麼的話更爲簡單,由於只須要從字母后一位開始,截取字母后面的全部就能夠直接轉換類型排序了。
相關文章
相關標籤/搜索