I am trying to figure out a format spec of to_char() that would give me the following result.
to_char(0.1, '[FORMAT_SPEC]')
gives 0.1 and:
to_char(1, '[FORMAT_SPEC]')
gives 1.
I've tried the following solutions:
to_char(0.1)
gives '.1'.
to_char(0.1, 'FM0.099')
gives 0.1, which is okay, however:
to_char(1, 'FM0.099')
gives 1.0, which is not okay.
Do you have any suggestions?
The precision returned needs to be consistent, so the only alternative is to use DECODE or CASE statements to conditionally return what you need:
CASE
WHEN INSTR(TO_CHAR(t.col), '.') = 0 THEN TO_CHAR(t.col)
ELSE TO_CHAR(t.col, 'FM0.099')
END
The example isn't great - it's not clear if your data will have values like 1.000 or values above one/etc.
EDIT Michael-O (2013-06-25): For those who need it idiot-proof, you may try:
case
when instr(to_char(<col>), (select to_char(0, 'FMD') from dual)) = 0
then to_char(<col>)
else to_char(<col>, 'FM999990D999')
end
It automatically observes the decimal separator. Adapt the the secodn format modal to your number size.
I just use this:
TRIM('.' FROM TO_CHAR(x, 'FM99990.999'))
Don't happen to have an Oracle instance handy to test this in, but I'd think that
TO_CHAR(1, 'FM0.999')
oughta do it.
Not sure what range of values you will be expecting but you could case out values < 1 versus those >= 1. Otherwise either the trailing 0 or the decimal is going to get in your way:
select val,
case when val < 1 then to_char(val, 'FM99990.9')
else to_char(val, 'FM99999')
end fmt
from (select 0.1 val from dual union all
select 1 from dual
)
/
VAL FMT
---------- --------
.1 0.1
1 1
Related
Hi i have the following column
Result
______
1.5
0.27
0.25
NEGATIVE
5.33
0.15
PROBLEM
NEGATIVE
POSITIVE
POSITIVE
i need to count how many negatives are when a result smaller than 1 is Also negative
when i use TO_NUMBER function i get an error ORA-01722 "invalid number"
'NEGATIVE' is a string not a number, hence ORA-01722 when you try to turn it into a number. So you need to handle those occurrences. Something like:
select count(
case when result = 'NEGATIVE' then 1
when result != 'PROBLEM' and to_number(result) < 1 then 1
else null
end) as tot_negatives
from your_table;
Strictly speaking 0.15 is not negative because it is greater than zero, but I've implemented your definition.
Note that I've assumed you don't have any other rogue non-numeric strings in your column, beyond 'NEGATIVE' and 'PROBLEM'. If there are others, then you need to handle them too.
On oracle version 12.2 and higher, you can use on conversion error with to_number function as following:
Select
Count(1) as result
From your_table
Where your_column = 'NEGATIVE'
Or to_number(your_column default 1 on conversion error) < 1 ;
Cheers!!
I have a function that calculates number of days
select (x * 0,5) from dual.
my problem is tha when x=1 i get .5 instead of 0,5.What i want to get is numbers in format 0.5,1,1.5,2,2.5 ..
Could you please give me a help with this.
I know this is old but I did the following, where x is datatype NUMBER(20,3)
CASE WHEN x < 1 THEN '0'
ELSE '' END
|| to_char(x)
I didn't want any trailing zeros but did want a leading zero if x was, say, 0.99 or 0.5
So I'm just using the regular to_char and adding a leading zero if x is less than 1.
Try to use:
select TO_CHAR(x * 0,5, '990,99') from dual
EDIT:
Try to create a function like this:
create function getDecimalFormat(x in number)
return varchar2
as
begin
return RTRIM(TO_CHAR(x, 'FM999999999999990.99'), '.');
end;
If you always want 1 decimal place use to_char to round
select TO_CHAR(28.324, '90.9') from dual;
returns
28.3
and
select TO_CHAR(28, '90.9') from dual;
returns
28.0
Hope this helps
I want to compare two numbers. Let's take i.e. 1 and 2.
I've tried to write the following query but it simply doesn't work as expected (Toad says: ORA-00923: FROM keyword not found where expected):
SELECT 1 > 2 from dual
The DECODE is something like a Switch case, so how can I get the result of an expression evalutation (i.e. a number comparison) putting it in the select list?
I have found a solution using a functions instead of an expression in the SELECT LIST: i.e.
select DECODE(SIGN(actual - target)
, -1, 'NO Bonus for you'
, 0,'Just made it'
, 1, 'Congrats, you are a winner')
from some_table
Is there a more elegant way?
Also how do I compare two dates?
There is no boolean types in sql (at least in oracle).
you can use case:
SELECT CASE when 1 > 2 THEN 1 ELSE 0 END FROM dual
But your solution (decode) is also good, read here
The SIGN() function is indeed probably the best way of classifying (in)equality that may be of interest to you if you want to test a > b, a = b and a < b, and it will accept date-date or numeric-numeric as an argument.
I'd use a Case statement by preference, rather than a decode.
Select
case sign(actual-target)
when -1 then ...
when 0 then ...
when 1 then ...
end
SELECT (CASE
WHEN (SIGN(actual - target) > 0 ) THEN
'NO Bonus for you'
ELSE
'Just made it' END)
FROM dual
you can compare two dates with sql
METHOD (1):
SELECT TO_DATE('01/01/2012') - TO_DATE('01/01/2012')
FROM DUAL--gives zero
METHOD (2):
SELECT CASE
when MONTHS_BETWEEN('01/01/2012','01/01/2010') > 0
THEN 'FIRST IS GREATER'
ELSE 'SECOND IS GREATER OR EQUAL' END
FROM dual
sorry i cant format the code the formatting toolbar disappeared !
do any one know why?
The current data of the table is:
a b
---------
-1 5
-11 2
-5 32
My request is to convert every data into a positive value.
Unfortunately, I forgot the name of the built-in function of SQL Server that enables to convert.
You are thinking in the function ABS, that gives you the absolute value of numeric data.
SELECT ABS(a) AS AbsoluteA, ABS(b) AS AbsoluteB
FROM YourTable
The best solution is: from positive to negative or from negative to positive
For negative:
SELECT ABS(a) * -1 AS AbsoluteA, ABS(b) * -1 AS AbsoluteB
FROM YourTable
For positive:
SELECT ABS(a) AS AbsoluteA, ABS(b) AS AbsoluteB
FROM YourTable
UPDATE mytbl
SET a = ABS(a)
where a < 0
Use the absolute value function ABS. The syntax is
ABS ( numeric_expression )
An easy and straightforward solution using the CASE function:
SELECT CASE WHEN ( a > 0 ) THEN (a*-1) ELSE (a*-1) END AS NegativeA,
CASE WHEN ( b > 0 ) THEN (b*-1) ELSE (b*-1) END AS PositiveB
FROM YourTableName
Update all negatives to positive
UPDATE my_table
SET value = ABS(value)
WHERE value < 0
Get all the negative
SELECT value FROM my_table
WHERE value < 0
Get all the negatives and convert them to positive
SELECT ABS(value) FROM my_table
WHERE value < 0
I have seen similar questions asked elsewhere on this site, but more in the context of optimization.
I am having an issue with the order of execution of the conditions in a WHERE clause. I have a field which stores codes, most of which are numeric but some of which contain non-numeric characters. I need to do some operations on the numeric codes which will cause errors if attempted on non-numeric strings. I am trying to do something like
WHERE isnumeric(code) = 1
AND CAST(code AS integer) % 2 = 1
Is there any way to make sure that the isnumeric() executes first? If it doesn't, I get an error...
Thanks in advance!
The only place order of evaluation is guaranteed is CASE
WHERE
CASE WHEN isnumeric(code) = 1
THEN CAST(code AS integer) % 2
END = 1
Also just because it passes the isnumeric test doesn't guarantee that it will successfully cast to an integer.
SELECT ISNUMERIC('$') /*Returns 1*/
SELECT CAST('$' AS INTEGER) /*Fails*/
Depending upon your needs you may find these alternatives preferable.
Why not simply do it using LIKE?:
Where Code Not Like '%[^0-9]%'
Btw, either using my solution or using IsNumeric, there are some edge cases which might lead one to using a UDF such as 1,234,567 where IsNumeric will return 1 but Cast will throw an exception.
Why not use a CASE statement to say something like:
WHERE
CASE WHEN isnumeric(code) = 1
THEN CAST(code AS int) % 2 = 1
ELSE /* What ever else if not numeric */ END
You could do it in a case statement in the select clause, then limit by the value in an outer select
select * from (
select
case when isNum = 1 then CAST(code AS integer) % 2 else 0 end as castVal
from (
select
Case when isnumeric(code) = 1 then 1 else 0 end as isNum
from table) t
) t2
where castval = 1