解決 Order By 將字串型別的數字 或 字串中含數字 按數字排序問題
oracle資料庫,欄位是varchar2型別即string,而其實存的是數字,這時候不加處理的order by的排序結果,肯定有問題
解決辦法:
(1)cast( 要排序的欄位名 as integer) ,注意 integer 小寫
(2)to_number (要排序的欄位名)
如以下例子:
表資料與結構: salary 為 varchar 型別
create table TEST_ROW_NUMBER_OVER( id varchar(10) not null, name varchar(10) null, age varchar(10) null, salary varchar(10) null ); insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(1,'a',10,'8000'); insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(1,'a2',11,'6500'); insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(2,'b',12,'13000'); insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(2,'b2',13,'4500'); insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(3,'c',14,'3000'); insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(3,'c2',15,'20000'); insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(4,'d',16,'30000'); insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(5,'d2',17,'1800');
以 salary 降序:
select id,name,age,salary,row_number()over(order by salary desc) rank
from TEST_ROW_NUMBER_OVER t
結果:
此結果根本不符合我們的預期:
解決辦法一:改寫:order by cast(salary as integer) desc
select id,name,age,salary,row_number()over(order by cast(salary as integer) desc) rank from TEST_ROW_NUMBER_OVER t
結果: 從結果看出,已經達到預期
增加一行字串double資料
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(5,'d2',17,'1888.88');
再執行
select id,name,age,salary,row_number()over(order by cast(salary as integer) desc) rank
from TEST_ROW_NUMBER_OVER t
結果:結果表明在 oracle 中 不論是 integer還是duoble 的 varchar 型別資料,都可以 通過 cast ( 欄位名 as integer ) 解決排序問題
解決辦法二:order by to_number(salary) desc
select id,name,age,salary,row_number()over(order by to_number(salary) desc) rank
from TEST_ROW_NUMBER_OVER t
結果:從結果看出,to_number 也一樣有效
再增加兩行資料:salary中含中文及數字,按數字進行排序
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(6,'e1',20,'李雷2333');
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(7,'e2',21,'張三23333');
排序:order by to_number(regexp_substr(salary,'[0-9]*[0-9]',1)) desc ,regexp_substr 為擷取方法,1為起始位置
select id,name,age,salary,row_number()over
(order by to_number(regexp_substr(salary,'[0-9]*[0-9]',1)) desc) rank
from TEST_ROW_NUMBER_OVER t
結果:
REGEXP_SUBSTR(String, pattern, position, occurrence, modifier)
__srcstr :需要進行正則處理的字串
__pattern :進行匹配的正則表示式
__position :起始位置,從第幾個字元開始正則表示式匹配(預設為1)
__occurrence :標識第幾個匹配組,預設為1
__modifier :模式('i'不區分大小寫進行檢索;'c'區分大小寫進行檢索。預設為'c'。)