How to mask date format in sql? - sql

There is open date 2015-05-19 10:40:14 and close date 2015-05-20 09:21:11
when I subtract them I am getting (close_date.date_value - open_date.date_value)
some 9.45104166666666666666666666666666666667E-01 value
I want to ignore the time 10:40:14 and 09:21:11 from 2 dates
similarly I am subtracting (SYSDATE - open_date.date_value) and get the number of days in number when I subtract 2 dates
Could anyone help me resolving this problem
case
when s then
(close_date.date_value - open_date.date_value)
else
(SYSDATE - open_date.date_value)
end as "dd",

You can use DATEDIFF function. Here is the code
SELECT DATEDIFF(DAY, CONVERT(DATETIME, '2015-05-19 10:40:14'), CONVERT(DATETIME, ' 2015-05-20 09:21:11'))

Try this
case
when status_name.list_value_id=9137981352013344123 then
(TRUNC(close_date.date_value) - TRUNC(open_date.date_value))
else
(TRUNC(sysdate) - TRUNC(open_date.date_value))
end as "e2e execution time",

From performance point of view, I would not use TRUNC as it would suppress any regular index on the date column. I would let the date arithmetic as it is, and ROUND the value.
For example,
SQL> SELECT SYSDATE - to_date('2015-05-20 09:21:11','YYYY-MM-DD HH24:MI:SS') diff,
2 ROUND(
3 SYSDATE - to_date('2015-05-20 09:21:11','YYYY-MM-DD HH24:MI:SS')
4 ) diff_round
5 FROM dual;
DIFF DIFF_ROUND
---------- ----------
29.1248264 29
SQL>

Related

ORA-00936: missing expression issue

I'm new to oracle sql and I'm trying to run the following query but getting above mentioned error.
SELECT CONVERT(DATETIME,CASE WHEN DATEPART (Hour, OrderTime) < 5
THEN DATEADD(Day, -1, CONVERT(date, ordertime))
ELSE CONVERT(date, ordertime)
END) AS ItemOrderTradingDate FROM TBL_ITEM
Please help.
It seems that you want to extract "hour" from a date column. If that's so, see these two options:
SQL> select ordertime,
2 to_char(ordertime, 'hh24') hour_1,
3 extract(hour from cast(ordertime as timestamp)) hour_2
4 from tbl_item;
ORDERTIME HOUR_1 HOUR_2
------------------- -------- ----------
06.04.2020 08:01:05 08 8
SQL>
Error you got when running Ankint's query was because extract - for certain values (hours, minutes, seconds) works on timestamps, not dates.
I'm not familiar with functions you used (convert, datepart, dateadd) so I can't tell what you really want to do once you find which hour it is. dateadd looks like you'd want to add (or subtract) 1 day from some data value. If that's so, then just do it: date arithmetic is (by default) done by days anyway:
SQL> select sysdate right_now,
2 sysdate + 1 tomorrow,
3 sysdate - 1 yesterday
4 from dual;
RIGHT_NOW TOMORROW YESTERDAY
------------------- ------------------- -------------------
06.04.2020 08:05:34 07.04.2020 08:05:34 05.04.2020 08:05:34
SQL>
You may try below query -
SELECT CASE WHEN EXTRACT(HOUR FROM OrderTime) < 5
THEN TRUNC(ordertime) - 1
ELSE TRUNC(ordertime)
END AS ItemOrderTradingDate
FROM TBL_ITEM

SQL - Julien Date (CYYDDD) to date

Unfortunately, this is my first approach with SQL!
I am creating with the following code a query between an oracle DB and Excel (Power Query).
select "$Table"."Order" as "Order",
"$Table"."NR" as "Nr",
"$Table"."JDDATE" as "JDDATE"
from "POOLDB2"."3112" "$Table"
WHERE "Key" >118001
AND "CodeAA" = 1
This code works!
Now I want to format the Julian Date (CYYDDD) - for example 118001 for the 01.01.2019 - to a normal date format.
Does anyone know, how to implement this into the code above?
Maybe something like :
select "$Table"."Order" as "Order",
"$Table"."NR" as "Nr",
DATEADD(DAY, JDDATE % 1000 - 1, DATEADD(year, JDDATE/1000, 0))
"$Table"."JDDATE" as "JDDATE"
from "POOLDB2"."3112" "$Table"
WHERE "Key" >118001
AND "CodeAA" = 1
Best regards
There are many different formats for Julian Date... In your use case, this should do it :
with t as (select 118001 jd from dual)
select to_char( to_date(to_char(1901 + floor(jd / 1000)),'YYYY') + mod(jd,1000) - 1, 'dd.mm.yyyy' ) from t
Yields : 01.01.2019
For Oracle,
select to_char(sysdate,'J') from dual; --To Julian Date
select to_date(2456143,'J') from dual; --To Normal Date
must work.
Edit: Sorry I didn't see oracle tag.
Edit: For the requested behavior by OP
select to_date(to_char(1901 + floor(118001 / 1000)),'YYYY') from dual;
You can use the 118001 value you have, split into separate year and day sections, by adding to the nominal starting date 1900-01-01 (based on your comment that 118001 is actually 2018-01-01, not 2019-01-01):
select date '1900-01-01'
+ floor(118001 / 1000) * interval '1' year
+ (mod(118001, 1000) - 1) * interval '1' day
from dual;
DATE'1900-
----------
2018-01-01
or by startng the fixed date a day earlier you can remove the explicit -1:
select date '1899-12-31'
+ floor(118019 / 1000) * interval '1' year
+ mod(118019, 1000) * interval '1' day
from dual;
DATE'1899-
----------
2018-01-19
This avoids having to build up a longer string to convert to a date, though you could do that (modifying #GMB's approach) as:
select to_date(to_char(1900 + floor(118001 / 1000)) || '-01-01', 'YYYY-MM-DD')
+ (mod(118001, 1000) - 1)
from dual;
You need to specify the month, at least, in the to_date() call as Oracle defaults to the current month if that is not supplied. That behaviour is tucked away in the documentation:
If you specify a date value without a time component, then the default time is midnight. If you specify a date value without a date, then the default date is the first day of the current month.
The first part of that is fairly well known and makes sense ; the second part is a bit less obvious, and doesn't make it clear that it applies to partial dates too - so ifyou don't supply a year then the current year is used; if you don't supply a month then the current month is used; but if you don't supply a day then the 1st is used.
You can see what it's doing with some test conversions:
select to_date('2018-12-25', 'YYYY-MM-DD') as demo_a,
to_date('12:34:56', 'HH24:MI:SS') as demo_b,
to_date('2019', 'YYYY') as demo_c,
to_date('07-04', 'MM-DD') as demo_d,
to_date('2019-01', 'YYYY-MM') as demo_e
from dual;
DEMO_A DEMO_B DEMO_C DEMO_D DEMO_E
------------------- ------------------- ------------------- ------------------- -------------------
2018-12-25 00:00:00 2018-12-01 12:34:56 2019-12-01 00:00:00 2018-07-04 00:00:00 2019-01-01 00:00:00

SQL oracle how to check if current date's day is greater than concrete day

I want to check if current sysdate's day is greater than 10.
By using sysdate function I get todays date, which is 2017.09.27. How can I check if 27 is greater than 10?
SELECT * from emp
where sysdate >= 'YYYY, DD, 10'
This is the only solution I can think of (it's ofcourse incorrect).
Thanks for help.
Use 'DD' date format to convert sysdate to a character string which is the day part of the date. i.e. '26' for today. Convert that string to a number and compare to 10.
SQL> select 'greater than 10' from dual where to_number(to_char(sysdate,'DD')) > 10;
'GREATERTHAN10'
---------------
greater than 10
SELECT * from emp
where TO_NUMBER(TO_CHAR(SYSDATE, 'DD')) >= 10
You could extract the day from the date:
select [ ... ]
where extract(day from SYSDATE) > 10;

Get Exact timestamp value?

I am trying to subtract some days from 'current_timestamp' and converting that to timestamp using to_timestamp() function in Oracle. But I am always getting start of day time, that is 12 AM.
When I execute
select to_timestamp(current_timestamp - 3) from dual;
It will give me result like,
18-FEB-14 12.00.00.000000000 AM
But I need exact deduction of 3 days from current time.
Thanks!!!!
select current_timestamp - 3 ts from dual;
or
SELECT SYSTIMESTAMP - INTERVAL '3' DAY AS day FROM dual;
Will give you time as well:
select sysdate - 3 from dual;
Edit based on your comment:
select to_timestamp(to_char(sysdate-3,'DD-Mon-RR HH24:MI:SS'),'DD-Mon-RR HH24:MI:SS') from dual;
Or more simply:
select systimestamp - 3 from dual
An important difference is that SYSDATE gives you server time, and CURRENT_TIMESTAMP gives you session time.
Also, according to the documentation, TO_TIMESTAMP operates on CHAR, VARCHAR2, NCHAR, or NVARCHAR2 data types, not DATE. So I think you need to look elsewhere:
SELECT CAST (SYSDATE AS TIMESTAMP) from dual;

SYSDATE but specify the time

I want to say the follow but substitute the date with SYSDATE but the time between is what I want to adjust. What would the syntax be?
where mydatefield between SYSDATE+'0001' and SYSDATE+'2359'
...
WHERE TO_CHAR( MOPACTIVITY.MOPNOTIFICATIONSENDAT , 'yyyy-mm-dd hh24:mi' )
BETWEEN '2013-07-26 00:00:01' AND '2013-07-26 23:59:59'
;
SYSDATE (or any other date column) in Oracle has the time component. So you need to strip that off and then add the hours/minutes/time condition.
Eg. to say current day 10:00 AM to 3:00 PM, you can say
date_column between (trunc(sysdate) + 10/24) and (trunc(sysdate) + 15/24)
Oracle date arithmetic works on the day level. so, +1 will give you the next day, 1/24 will give you an hour and 10/24 will give you 10:00 AM in the current day.
SQL> alter session set nls_date_format = 'DD-Mon-YYYY HH:MI:SS AM';
Session altered.
1 select sysdate,
2 trunc(sysdate),
3 trunc(sysdate) + 10/24,
4 trunc(sysdate) + 15/24
5* from dual
SQL> /
SYSDATE 26-Jul-2013 06:26:07 PM
TRUNC(SYSDATE) 26-Jul-2013 12:00:00 AM
TRUNC(SYSDATE)+10/24 26-Jul-2013 10:00:00 AM
TRUNC(SYSDATE)+15/24 26-Jul-2013 03:00:00 PM
For your question, you seem to be interested between current day and next day, so you can try adding + 1 to the date directly, once you strip the time component.
date_column >= trunc(sysdate) and
date_column < trunc(sysdate)+1
The best way to do this is to leave your MOPACTIVITY.MOPNOTIFICATIONSENDAT as a DATE type. That allows Oracle to optimize the query if there happens to be an index on the column. I'd recommend something like this:
WHERE MOPACTIVITY.MOPNOTIFICATIONSENDAT >= TRUNC(SYSDATE)
AND MOPACTIVITY.MOPNOTIFICATIONSENDAT < TRUNC(SYSDATE) + 1
That boils down to "greater than or equal to today at midnight" and "less than tomorrow at midnight".
We can also trunc both the dates and then compare the result
where TRUNC(MOPACTIVITY.MOPNOTIFICATIONSENDAT) = TRUNC(SYSDATE)
TRUNC Removes the timestamp from the dates