Oracle - Date - Date Issue - oracle

I am trying to calculate the difference between dates. I only need the decimal of a day so date - date is all I need.
The issue I have is, this works for some records but not others, with no real pattern. Using the below:
select (case when c.call_answered_date is null then c.call_ended_date - c.call_entered_queue_date else 0 end),
C.CALL_ENTERED_SYSTEM_DATE, C.CALL_ENTERED_QUEUE_DATE, C.CALL_ENDED_DATE
I get
abd_wait call_entered_system_date call_entered_queue_date call_ended_date
-------- ------------------------ ----------------------- ---------------
5.78703703703704E-5 06/01/2020 12:30:00 06/01/2020 12:30:11 06/01/2020 12:30:16
0.000844907407407407 06/01/2020 12:35:38 06/01/2020 12:35:49 06/01/2020 12:37:02
So the second line works as expected, the first does not. But I do not know why.
I need them to all be a decimal of a day like the second line.
Please help.

The first line has the correct value and is just in scientific notation: 5.78703703703704E-5
is the same as: 0.0000578703703703704 which is 5 seconds expressed as a fraction of a day: (16-11)/24/60/60. The value is still a (decimal) number it is just displayed in a slightly different format.
If you want it as a fixed formatted decimal string then use TO_CHAR to give the number an explicit format:
select case
when c.call_answered_date is null
then TO_CHAR(
c.call_ended_date - c.call_entered_queue_date,
'0.000000000000000000'
)
else '0'
end,
C.CALL_ENTERED_SYSTEM_DATE,
C.CALL_ENTERED_QUEUE_DATE,
C.CALL_ENDED_DATE
FROM your_table c

Related

How to compare centuries in Oracle Database?

I could fix this issue by declaring the variable as DATE and not as VARCHAR.
I have a pre-configured constant varchar2 value in a table.
I have declared lv_constants_config as VARCHAR2 and not as DATE.
I think that is the reason why I am facing problem.
SELECT * FROM constants_config
------------------------------
constant1
---------
01/01/3000
In my PL/SQL code I am retrieving this value as,
SELECT TO_DATE(constant1,'MM/DD/YYYY') --I also tried with RRRR instead of YYYY.
INTO lv_constants_config
FROM constants_config;
I am comparing this value with the value input by the User (from UI).
IF iv_input_date > lv_constants_config
THEN
--do this
ELSE
--do that
END IF;
My problem is 3000 is getting wrongly interpreted as 00.
Eg., 01/01/3000 is getting interpreted as 1st Jan, 2000
01/01/3049 is getting interpreted as 1st Jan, 2049
01/01/3050 is getting interpreted as 1st Jan, 2050
How can I compare dates with century value as it is?

Single Month Digit Date Format issue in Oracle

Am getting the below issue when am using 'mon-d-yyyy' to convert date to char, as i need a single day digit for values from 1 to 9 days in a month.
When i use the 'mon-d-yyyy' format, am losing out on 5 days and getting a wrong date. Any help on this would be great.
select to_char(sysdate-22,'mon-d-yyyy') from dual;--aug-2-2017
select to_char(sysdate-22,'mon-dd-yyyy') from dual;--aug-07-2017
select sysdate-22 from dual;--07-AUG-17 11.06.43
In Oracle date formats, d gets the day of week. The 2 in your output means monday, not august the 2nd.
Try using Fill Mode as Format Model Modifier
select to_char(sysdate-22,'mon-fmdd-yyyy') from dual;
One option might be to piece together the date output you want:
SELECT
TO_CHAR(sysdate-22, 'mon-') ||
TRIM(LEADING '0' FROM TO_CHAR(sysdate-22, 'dd-')) ||
TO_CHAR(sysdate-22, 'yyyy')
FROM dual;
The middle term involving TRIM strips off the leading zeroes, if present, from the date.
Output:
Demo here:
Rextester
SQL>SELECT TO_CHAR(TO_DATE('29-AUG-2017','DD-MON-YYYY') - 22,'"WEEKDAY :"D, MON-FMDD-YYYY') "Before22Days" FROM DUAL;
D- Gives you a numeric weekday(2nd weekday in a week) on AUG-07-2017.
DD-Gives a Numeric Month Day i.e,07th
FMDD-Gives 7th
Before22Days
----------------------
WEEKDAY :2, AUG-7-2017

Date Conversion from M20161 to Jan16

How to convert M20161 to Jan-16 in Oracle where 2016 is the year and 1 is the month.
If "M" literal is going to be always present, then just enclose it in double quotes in the format mask. Since there is no day part it'll default to first day of the month.
select to_date('M20161', '"M"YYYYMM') as res
from dual
Result:
RES
---------
01-JAN-16
To display the date in desired Jan-16 format, use TO_CHAR() function and Mon-YY format model.
select to_char(to_date('M20161', '"M"YYYYMM'), 'Mon-YY') as res
from dual
Result:
RES
------
Jan-16

Decimal place require in Oracle

case 1: SELECT TO_CHAR(12345.6789, '99999D99') FROM dual;
Output: 12345.67
case 2: SELECT TO_CHAR(12345.6789, '999D99') FROM dual;
Output: ######
case 3: SELECT TO_CHAR(12345, '99999D99') FROM dual;
Output: 12345.00
case 4: SELECT TO_CHAR(12345.1, '99999D99') FROM dual;
Output: 12345.10
Here Problem is if we don't know how many digits before decimal then how to manage for correct answer.[only case 1,3,4 can resolved using by TO_CHAR but how to solve for case 2.]
In this case the simplest answer might be to not supply a format model at all, but truncate or round the value to two decimal places:
SELECT TO_CHAR(ROUND(12345.6789, 2)) as rounded,
TO_CHAR(TRUNC(12345.6789, 2)) as truncated
FROM dual;
ROUNDED TRUNCATED
-------- ---------
12345.68 12345.67
From the documentation:
If you omit fmt, then n is converted to a VARCHAR2 value exactly long enough to hold its significant digits.
Otherwise you'd need to supply a format model that allowed for the maximum size of your number; if it's unrestricted you'd need 36 nines, the decimal separator, and two more nines. The result would be padded with spaces so you might also want to trim it, depending on how you'll use the string value.
SELECT TO_CHAR(12345.6789, '999999999999999999999999999999999999D99') as val
FROM dual;
VAL
----------------------------------------
12345.68
You could also do that flexibly by using the length of the truncated value (i.e. once the decimal places have been removed):
SELECT TO_CHAR(12345.6789,
lpad('9', length(trunc(12345.6789)), '9') || 'D99') as val
FROM dual;
VAL
---------
12345.68
But that seems unnecessarily complicated when you can let Oracle work it out for you.
However, if you want the decimals to show trailing zeros then you might need to use that method; but with zeros after the decimal separator:
SELECT TO_CHAR(12345.6, lpad('0', length(trunc(12345.6)), '9') || 'D00') as val
FROM dual;
VAL
---------
12345.60
... which addresses the 3rd and 4th cases you added. I've made it show a leading zero for values less than 1 as well; the generated format model in this case is '99990D00'. The number of nines will still vary depending on the size of your number.
By default Oracle still leaves a space at the start for a potential minus sign. You can avoid that with the FM format modifier:
SELECT TO_CHAR(12345.6, 'FM'
|| lpad('0', length(trunc(12345.6)), '9') || 'D00') as val
FROM dual;
VAL
--------
12345.60
You could always go with the maximum number of digits you expect to be present in the input. If there are fewer digits in the input than your format specifier, it wouldn't affect the outcome in anyway. For instance,
select to_char(12323.5553,'99999D99') from dual
would produce,
123.56
As you said, the length of the input is unknwon. So why would you use a fixed length formater for somthing that is unknown? Does not work. Read your input as String from the beginning and manipulate it as String or even better - BLOB.
Well, to do the rounding correct might be tricky.
So, best check your data if the numbers will realy get so big, because that would mean a lot of work and trouble.
If not more than 38 Digits are needed, you can go with decimal or numeric datatype and (if you insist on a formatter) use the TM formatter for example.
SELECT to_char(cast(1234.456 as decimal( *,2)), 'TM') as a FROM dual
or take the advice that was given above by the other posters.

Oracle to_char function with a number format that has an arbitrary precision and certain scale

This one is pretty simple actually yet I wasn't able to find anything useful.
In my SQL query I have some rounded numbers with a single scale value - round(number,1). If the numbers are rounded to some decimal digit it prints in the format '9,9'.
On the other hand if the numbers are rounded to an integer, only the integer value without the zero after comma is printed although I want my query to select the numbers in '9,9' format even the decimal digit is zero.
In short, I think I need something like for example
to_char((select round(121.01,1), from dual), '*,1') ; to output 121,0.
What is the best way to do this? Thanks in advance
Korhan
All you have to do is specify the number of decimal points you want in your to_char. The problem with using format masks is that you need to specify the number of numbers you want in front of your decimal point.
SQL> select to_char(round(121.01,1),'999.9') from dual;
TO_CHA
------
121.0
SQL> select to_char(round(121.4,1),'999.9') from dual;
TO_CHA
------
121.4
SQL> select to_char(round(121,1),'999.9') from dual;
TO_CHA
------
121.0
SQL> select to_char(round(5121,1),'999.9') from dual;
TO_CHA
------
######
SQL>
There are a number of other formatting options.
Use 0 instead 9 for decimal places:
SELECT TO_CHAR( ROUND( 121.01, 1 ), '990D0' ) num FROM DUAL;
NUM
------
121.0
This simple query may help you,
select to_char(round(121.01,1), '999.0') from dual;
In to_char function:
9 - indicate to block/hide zeros in the output.
0 - indicate to show zero in the output at anywhere in before/after decimal point.
Note:
No. of '9/0's in before/after decimal point is number of digits which you want to display beore/after decimal point.

Resources