2013-08-21 2 views
2

У меня есть столбец DOOR, который является VARCHAR2 в таблице АДРЕС. Я хочу отсортировать колонку DOOR.Сортировка столбца varchar как целочисленное значение в запросе Oracle

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 

Я попытался преобразовать Doot в числовое значение с помощью to_number в

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

, но он дает мне ошибку ORA-01722.

ответ

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

Создание собственной PL функции/SQL не будет очень эффективным и есть некоторые дополнительные вещи, которые вы добавили, которые вам не нужно. Вы также можете использовать коды ASCII для его улучшения; он будет таким же, но цифры будут удалены, например: http://www.sqlfiddle.com/#!4/0d064/1. Кроме того, что произойдет, если значение C? – Ben

+0

yes correct Я предположил только 2 значения, но если мы вернем значение ascii, скажем, для a вернем 97, и в столбце 97,98,99 есть значения, то он будет находиться между этими записями. – swapy

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 

Это первый ставит не-числовые значения первого. Второе предложение сортируется в алфавитном порядке. Третий и четвертый - для чисел. Сортируя для длины до значения, вы получите номера в порядке.

1

(Этот подход предполагает, что не существует какие-либо смешанные ценности, как «234abc567».)

Так, идя старую школу ... просто 0 колодок строки до максимальной длины колонны так, чтобы они Я правильно сортирую как символы. Но чтобы сначала получить «нечисловые» значения для сортировки, сбрасывать нечисловые значения, сначала поместите NULL и добавьте значения.

select door 
    from address 
order by case when replace(translate(door, '', '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. 
-1

использовать ниже запрос

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

Можете ли вы задать вопрос по этому запросу? –