我有一个 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
。
答案 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);