3

I have a column DOOR which is a VARCHAR2 in a Table ADDRESS. I want to sort the column DOOR.

DOOR contains only two digits and no - sign

currently when I use the query

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

I get the following result:

a
b
1
10
11
2
3
31

But I want the result to look like this:

a
b
1
2
3
10
11
31

I tried to convert DOOT into a numeric value using to_number as

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

but it is giving me an error ORA-01722.

4 Answers 4

3

You can do this with the logic in the 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

This first puts the non-numeric values first. The second clauses sorts these alphabetically. The third and fourth are for numbers. By sorting for the length before the value, you will get the numbers in order.

Sign up to request clarification or add additional context in comments.

Comments

3

ORA-01722 error coming because of value 'a' ,'b', Go for custom function which will take varchar and return number to convert , use custom function in order by clause of your query.

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;

Add when condition as in required. now assumed it can have only A B. for rest it will return default.

2 Comments

Creating your own PL/SQL function would not be very efficient and there's some additional things you've added which you don't need to. You could also use ASCII codes to improve it; it'll be the same but the numbers would be removed, for instance: sqlfiddle.com/#!4/0d064/1. Also, what happens if the value is C?
yes correct i assumed only 2 values, but if we return ascii value say for a we return 97, and there are values in column 97,98,99 then it will come in between those records.
1

(This approach assumes that there aren't any mixed values like "234abc567".)

So, going old school...just 0-pad the strings to the maximum length of the column so that they'll sort properly as characters. But, to get the "non-numeric" values to sort first, nullify non-numeric values, put the NULLs first and padded values after that.

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.

Comments

0

use the below query

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

1 Comment

Can you specify the question for this query?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.