2013-08-08 2 views
0

Работает на 10g.Конвертация нескольких десятичных знаков на номер

У меня есть регулярное выражение, которое возвращает записи числовые значения, но в некоторых случаях возвращает несколько десятичных точек, таких как 68.70125195853.50

Что мне нужно, это способ вернуть только два знака после запятой после первого десятичного знака, например 68,70.

Я пробовал встроенные функции, такие как to_char, to_number и round.

Я был бы очень признателен за вашу помощь.

+1

отредактируйте ваш вопрос, чтобы включить ваши лучшие догадки о том, что вы пробовали. Еще лучше, не можете ли вы установить это у источника. поиск строк занимает много времени, особенно если их у них много. Удачи. – shellter

+0

Если вы получаете более 1 десятичной точки, разве это не означает, что вы неправильно ее извлекаете? – Noel

ответ

0

Try:

CAST(value AS Decimal(15,2)) 

Если вы просто обеспокоены "смотреть" чисел, вы можете использовать:

SELECT TO_CHAR(num, '999,999,990.00') 
    FROM MyTable 
0

Вот один метод:

select (case when val like '%.%' 
      then cast(substr(t.val, 1, instr(val, '.')+2) as float) 
      else cast(val as float) 
     end) 
from (select '68.70125195853.50' as val from dual) t; 

Оператор case проверяет хотя бы одну десятичную точку.

1

Это должно работать, если вам нужны только первые два десятичных знака. Обратите внимание: без выборочных данных ответ может быть выключен; если да, пожалуйста, приведите примеры некоторых из значений у вас возникли проблемы с:

SELECT CAST(REGEXP_SUBSTR(myVal, '(\d+\.\d{0,2})|(\d+)') AS NUMBER(20, 2)) 
FROM myTable 
WHERE REGEXP_LIKE(myVal, '(\d+\.\d{0,2})|(\d+)') 

Регулярное выражение должно работать без десятичного знака, а также с одним или двумя знаками после запятой. Обратите внимание, что все после второго десятичного разряда будет усечено, поэтому округление не произойдет. Если вы хотите округлить, измените \d{0,2} на \d+, а CAST позаботится об округлении.

В статье WHERE игнорируются столбцы, которые не содержат числа, что предотвращает ошибки литья.


Добавление: вот объяснение регулярных выражений. Он ищет один из двух шаблонов.

Первый образец: (\d+\.\d{0,2}). Это ловит цифры с десятичными знаками.

  • ( ==> разграничивает первый шаблон, определяющий начало первого рисунка
  • \d+ ==> соответствует одному или более цифр (\d означает "любую цифру")
  • \. ==> матч период (период является «специальный» символ так, чтобы соответствовать его буквально вам нужно избавиться от нее с косой черты (\)
  • \d{0,2} ==> матч ноль, один или две цифры
  • ) ==> ограничивает первый шаблон, определяющий конец первого рисунка

Второй образец: (\d+).Он ловит цифры без десятичных знаков.

  • ( ==> определяет начало второго шаблона
  • \d+ ==> соответствует одному или более цифр
  • ) ==> определяет конец второго шаблона

Наконец , два шаблона соединяются с оператором OR (|), поэтому вы получите соответствие, если любой шаблон совпадает.

  • (первая модель)|(второго узора)

Порядок узоров важен здесь, потому что «число с десятичными знаками» также соответствует «числу без десятичных знаков» образец ; поэтому шаблон «число с десятичными знаками» является первым.

+0

Мне удалось добавить функцию трансляции в мое регулярное выражение и получить необходимый результат. Мне действительно нужно изучить синтаксис regexp. Не возражаете ли вы преодолеть свой SUBSTR? – user3561134

+0

Я добавил шаг за шагом регулярное выражение к моему ответу. Надеюсь, это поможет - это довольно сложно объяснить регулярным выражениям :) –

0

Вы могли бы использовать следующее регулярное выражение внутри to_number

to_number(
    regexp_substr(
     '68.70125195853.50', 
     '^[0-9]+(\.[0-9]{1,2})?' 
    ) 
) 

В словах: начинается с серией цифровых символов, в конце концов, за которым следует точка, то из 1 более 2 цифровых символов.