在Oracle查询中将varchar列排序为整数值

时间:2013-08-21 17:03:52

标签: sql oracle sorting oracle10g

我有一个 DOOR 列,它是表 ADDRESS 中的VARCHAR2。我想对列 DOOR 进行排序。

DOOR仅包含两位数字且没有-符号

目前我在使用查询时

select sname, door, zip from address a order by door

我得到以下结果:

a
b
1
10
11
2
3
31

但我希望结果看起来像这样:

a
b
1
2
3
10
11
31

我尝试使用to_number DOOT 转换为数值

select sname, to_number(door) dnr, zip from address a order by dnr

但它给了我一个错误ORA-01722

4 个答案:

答案 0 :(得分:3)

ORA-01722错误因为价值'a','b'而来, 转到自定义函数,它将使用varchar和返回数字进行转换,在查询的order by子句中使用自定义函数。

CREATE OR REPLACE FUNCTION tonumber (no_str varchar2)
        RETURN number IS
           num number := 0;
        BEGIN
           RETURN to_number(no_str);
        EXCEPTION  -- exception handlers begin A < B < 1 < 2
           WHEN value_error THEN  -- handles all other errors
               dbms_output.put_line('in other exception catch.');
               CASE
                  WHEN ( upper(no_str) = 'B' )  THEN  return -1;
                  WHEN ( upper(no_str) ='A') THEN return -2;
                  ELSE return -999;
               END CASE;
        END;

根据需要添加条件。现在假设它只有A B.休息它将返回默认值。

答案 1 :(得分:3)

您可以使用order by

中的逻辑执行此操作
order by (case when regexp_like(door, '^[0-9]*$') = 0 then 1 else 0 end) desc,
         (case when regexp_like(door, '^[0-9]*$') = 0 then door end),
         length(door),
         door

首先将非数字值放在第一位。第二个条款按字母顺序排序。第三和第四是数字。通过对值之前的长度进行排序,您将按顺序获取数字。

答案 2 :(得分:1)

(这种方法假设没有像“234abc567”那样的混合值。)

所以,去旧学校......只需将字符串0填充到列的最大长度,这样它们就可以正确排序为字符。但是,要首先对“非数字”值进行排序,请使非数字值无效,然后将NULL设置为第一个,并在此之后添加填充值。

select door
  from address
 order by case when replace(translate(door, '012345679', '0000000000'), '0', '') is null 
               then lpad(door, 10, '0') -- value was entirely made of digits (change the 10 to the max width of the column)
               else null 
           end nulls first
        , door -- sorting within the group of NULL rows generated in the previous expression.

答案 3 :(得分:-1)

使用以下查询

  SELECT PUMP_NAME 
    FROM MASTER.PUMPS
ORDER BY LPAD(PUMP_NAME, 10);