Reputation: 1
Working on 10g.
I have a regexp that returns the records numeric values, but in some cases returns multiple decimal points such as 68.70125195853.50
What I need is a way to only return the two decimal places after the first decimal, like 68.70.
I have tried built-in functions like to_char, to_number, and round.
I would very much appreciate your help.
Upvotes: 0
Views: 2891
Reputation: 2450
You could probably use the following regexp inside a to_number
to_number(
regexp_substr(
'68.70125195853.50',
'^[0-9]+(\.[0-9]{1,2})?'
)
)
In words: begins with a series of numeric chars, eventually followed by a dot then from 1 to 2 more numeric chars.
Upvotes: 0
Reputation: 26333
This should work if you need only the first two decimal places. Note that without sample data the answer could be off; if so please provide examples of some of the values you're having trouble with:
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+)')
The regex should work with no decimal place, as well as with one or two decimal places. Note that anything after the second decimal place will be truncated, so no rounding will occur. If you want rounding, change the \d{0,2}
to \d+
, and the CAST
will take care of rounding.
The WHERE
clause ignores columns that don't contain a number, which prevents casting errors.
Addendum: here's an explanation of the regex. It looks for one of two patterns.
The first pattern is (\d+\.\d{0,2})
. This catches numbers with decimal places.
(
==> delimits the first pattern, defining the beginning of the first pattern\d+
==> match one or more digits (\d
means "any digit")\.
==> match a period (the period is a "special" character so to match it literally you need to escape it with the slash (\
)\d{0,2}
==> match zero, one or two digits)
==> delimits the first pattern, defining the end of the first patternThe second pattern is (\d+)
. It catches numbers without decimal places.
(
==> defines the beginning of the second pattern\d+
==> match one or more digits)
==> defines the end of the second patternFinally, the two patterns are joined with the OR
operator (|
) so you'll get a match if either pattern matches.
(
first-pattern)|(
second-pattern)
The order of the patterns is important here, because a "number with decimals" also matches the "number without decimals" pattern; that's why the "number with decimals" pattern is first.
Upvotes: 1
Reputation: 5722
Try:
CAST(value AS Decimal(15,2))
If you're just concerned with the "look" of the numbers, you can use:
SELECT TO_CHAR(num, '999,999,990.00')
FROM MyTable
Upvotes: 0
Reputation: 1269563
Here is one method:
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;
The case
statement is checking for at least one decimal point.
Upvotes: 0