3

我有一列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

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

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

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

4

4 回答 4

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

这首先将非数字值放在首位。第二个子句按字母顺序排列。第三和第四是数字。通过在值之前对长度进行排序,您将按顺序获得数字。

于 2013-08-21T17:24:48.053 回答
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;

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

于 2013-08-21T17:05:27.017 回答
1

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

所以,去老学校......只需将字符串填充到列的最大长度,以便它们作为字符正确排序。但是,要首先对“非数字”值进行排序,请取消非数字值,将 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.
于 2013-08-21T20:07:36.120 回答
-1

使用以下查询

  SELECT PUMP_NAME 
    FROM MASTER.PUMPS
ORDER BY LPAD(PUMP_NAME, 10);
于 2016-03-11T12:44:10.537 回答