Oracle sql date interval - sql

Please help me B is correct?
or C

Your best option is to try it.
SQL> alter session set nls_date_format = 'dd_mm_yyyy';
Session altered.
SQL> -- A
SQL> select to_char(to_date('29-10-2019') + interval '2' month + interval '6' day
2 + interval '120' second, 'dd-mon-yyyy') as datum from dual;
DATUM
-----------
04-jan-2020
SQL> -- B
SQL> select to_char(to_date('29-10-2019') + interval '3' month + interval '7' day
2 + interval '120' second, 'dd-mon-yyyy') as datum from dual;
DATUM
-----------
05-feb-2020
SQL> -- C
SQL> select to_char(to_date('29-10-2019') + interval '2' month + interval '4' day
2 + interval '120' second, 'dd-mon-yyyy') as datum from dual;
DATUM
-----------
02-jan-2020
SQL> -- D
SQL> select to_char(to_date('29-10-2019') + interval '2' month + interval '6' day
2 + interval '120' second, 'dd-mon-yyyy') as datum from dual;
DATUM
-----------
04-jan-2020
SQL> -- E
SQL> select to_char(to_date('29-10-2019') + interval '2' month + interval '5' day
2 + interval '120' second, 'dd-mon-yyyy') as datum from dual;
DATUM
-----------
03-jan-2020
SQL>
So - yes, C is correct.

None, all the queries are syntactically invalid and will raise exceptions as:
they have backticks instead of single quotes;
there should be a second quote in INTEVAL '120 SECOND and INTERVAL is misspelt; and
around the format model for the TO_CHAR function the quotes are missing and so is the preceding comma to separate the arguments.
If you ignore the (many) syntax errors then you start with 2019-10-29 and want to get to 2020-01-02; there is a difference of 2 months (which would take you to 2019-12-29) and 4 days. The seconds do not matter as they are not being displayed due to the NLS settings. This would give the answer C.

Related

Add minutes to an Oracle date

I am trying to add minutes to my sql but no error and no data.
This is my sql
select distinct mo.reference_no payment_id, mo.dcn message_id,
mo.amount, mo.ccy, decode (mo.msg_status, 'R', 'Repair', 'P',
'Processed','N','Ungenerated','G','Generated',mo.msg_status)
message_status, to_char
(MO.INSERT_TIME,'DD-MM-YYYY HH24:MI:SS')
paym_date, mo.branch_date, mo.maker_id
from table1 mo
left join table2 mi
on mo.reference_no = mi.generated_ref_no
where mo.swift_msg_type = 103
and mo.ccy = 'XXX' and mo.branch_date = trunc(sysdate)
and mo.msg_status in('R','N','G','P')
order by PAYM_DATE desc;
And I want to add 5 minutes to (MO.INSERT_TIME,'DD-MM-YYYY HH24:MI:SS')
So I want my sql show me after 5 minutes for this column (MO.INSERT_TIME,'DD-MM-YYYY HH24:MI:SS')
I wrote sql like that
select distinct mo.reference_no payment_id, mo.dcn message_id,
mo.amount, mo.ccy, decode (mo.msg_status, 'R', 'Repair', 'P',
'Processed','N','Ungenerated','G','Generated',mo.msg_status)
message_status, to_char
(MO.INSERT_TIME,'DD-MM-YYYY HH24:MI:SS')
paym_date, mo.branch_date, mo.maker_id
from table1 mo
left join table2 mi
on mo.reference_no = mi.generated_ref_no
where mo.swift_msg_type = 103
and mo.ccy = 'XXX' and mo.branch_date = trunc(sysdate)
and MO.INSERT_TIME = to_date (sysdate,'DD-MM-YYYY HH24:MI:SS') + INTERVAL '5' MINUTE
and mo.msg_status in('R','N','G','P')
order by PAYM_DATE desc;
And after 5 minutes I am selecting this sql and their is no data. Can you explain why?
This is what you used:
and MO.INSERT_TIME = to_date (sysdate,'DD-MM-YYYY HH24:MI:SS') + INTERVAL '5' MINUTE
It is wrong because you're applying TO_DATE function to SYSDATE which already returns DATE datatype, so there's no point in doing it.
SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';
Session altered.
SQL> select sysdate,
2 sysdate + interval '5' minute
3 from dual;
SYSDATE SYSDATE+INTERVAL'5'
------------------- -------------------
10.01.2023 09:49:05 10.01.2023 09:54:05
SQL>
It is probably not very likely that MO.INSERT_TIME will exactly be the same as SYSDATE (which is right now) + 5 minutes, which is in the future.
Perhaps you'd rather set that condition to e.g. rows inserted during last 5 minutes (which makes more sense to me):
and MO.INSERT_TIME >= sysdate - INTERVAL '5' MINUTE
DATE + NUMBER where number can be fractional and is interpreted as days, and a minute is 1/(24*60) of a day...

Column based on time range in Oracle

I have a sales table with created datetime, my business hours are from 9 AM to 2 AM in the night on the following day. I am trying to convert the dates into my business date.
01/08/22 09:39:12.000000000 AM +04:00
Lets say I have a sale at 1 AM, this sale has to be considered in the previous day.
Any function that can help me solve this issue would be appreciated
It might be a bit of an overkill, but you could just use EXTRACT:
WITH dat AS
(
SELECT to_date('01/08/22 09:39:12','DD/MM/YY HH24:MI:SS') AS t_stmp FROM dual UNION ALL
SELECT to_date('02/08/22 01:03:15','DD/MM/YY HH24:MI:SS') FROM dual UNION ALL
SELECT to_date('02/08/22 08:27:33','DD/MM/YY HH24:MI:SS') FROM dual UNION ALL
SELECT to_date('02/08/22 14:11:51','DD/MM/YY HH24:MI:SS') FROM dual UNION ALL
SELECT to_date('02/08/22 02:01:15','DD/MM/YY HH24:MI:SS') FROM dual
)
SELECT CASE WHEN EXTRACT(HOUR FROM CAST(t_stmp AS TIMESTAMP)) BETWEEN 2 AND 8 THEN -1
ELSE 0
END + TRUNC(t_stmp,'DD') AS business_date
FROM dat;
business_date
01.08.2022
02.08.2022
01.08.2022
02.08.2022
01.08.2022
It looks like you just need to make a 2 hour shift to get your sales in the right date. You can add or substract hours from DATE/DATETIME/TIMESTAMP data type. If your column is TIMESTAMP then it would be like this:
-- when selecting data for date of sales
SELECT TRUNC(your_column_name - INTERVAL '2' HOUR, 'dd') "SALE_DATE"
-- And/Or
WHERE TRUNC(your_column_name - INTERVAL '2' HOUR, 'dd') = :DATE_OF_SALES
-- TRUNC function always returns DATE datatype
--
-- The opposite conversion would be
CAST(your_datetime_column + INTERVAL '2' HOUR as TIMESTAMP) ...
Here is the small sample with result:
SELECT
to_char(SYSDATE, 'dd.mm.yyyy hh24:mi:ss') "DATETIME",
to_char(SYSDATE - INTERVAL '2' HOUR, 'dd.mm.yyyy hh24:mi:ss') "DATETIME_MINUS_2H",
to_char(SYSDATE + INTERVAL '2' HOUR, 'dd.mm.yyyy hh24:mi:ss') "DATETIME_PLUS_2H",
to_char(SYSDATE - INTERVAL '10' HOUR, 'dd.mm.yyyy hh24:mi:ss') "DATETIME_MINUS_10H"
FROM
DUAL
--
-- R e s u l t
--
-- DATETIME DATETIME_MINUS_2H DATETIME_PLUS_2H DATETIME_MINUS_10H
-- ------------------- ------------------- ------------------- -------------------
-- 07.08.2022 09:58:38 07.08.2022 07:58:38 07.08.2022 11:58:38 06.08.2022 23:58:38
The last column now has the date from day before.

last day/time of month

How do I get the last day of the month to be 11:59:59 pm? Right now it is showing 05/31/2019 12:00 AM. If I just do sysdate it just shows the time I ran it. Thanks.
LAST_DAY(TRUNC(SYSDATE,'MM'))
Try adding one day to the last day of the current month, then subtracting one minute:
SELECT
LAST_DAY(TRUNC(SYSDATE,'MM')) + INTERVAL '1' DAY - INTERVAL '1' SECOND
FROM dual;
Or, if you want to also see the time component, use CURRENT_TIMESTAMP in place of SYSDATE:
SELECT
LAST_DAY(TRUNC(CURRENT_TIMESTAMP,'MM')) + INTERVAL '1' DAY - INTERVAL '1' SECOND
FROM dual;
This outputted:
30.06.2019 23:59:59
The oldfashioned way would be to subtract a second (that's what 1 / (24*60*60) represents as there are 24 hours in a day, 60 minutes in an hour and 60 seconds in a minute) from the first day of the next month (and that's what trunc(add_months(sysdate, 1)) does):
SQL> select sysdate today,
2 trunc(add_months(sysdate, 1)) - 1/(24*60*60) result
3 from dual;
TODAY RESULT
---------------------- ----------------------
06/01/2019 07:52:40 AM 06/30/2019 11:59:59 PM
SQL>
I would use:
SELECT TRUNC(SYSDATE, 'MM') + INTERVAL '1' MONTH - INTERVAL '1' SECOND
FROM dual;
(This has one less step than Tim's solution.)
Or in the older-fashioned method:
SELECT ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1) - 1/(24*60*60)
If you convert this to a timestamp, you will see the time value:
SELECT CAST(TRUNC(sysdate, 'MM') + INTERVAL '1' MONTH - INTERVAL '1' SECOND as TIMESTAMP)
FROM dual;

Oracle - fetch first 3 days record of the current month

I need to fetch first 3 days record of the current month from Oracle database. Something like below,
Select * from test.purchase where create_ts=( first 3 days of the current month)
Select *
from test.purchase
where create_ts between trunc(sysdate,'mm') and trunc(sysdate,'mm') + 3
You can get the first day of the current month with the trunc(date) function, using the MM date format element.
select to_char(trunc(sysdate, 'MM'), 'YYYY-MM-DD Hh24:MI:SS') from dual;
TO_CHAR(TRUNC(SYSDA
-------------------
2017-06-01 00:00:00
You can then use date arithmetic to either add a number of days or an interval representing that number to get the fourth day of the month:
select to_char(trunc(sysdate, 'MM') + 3, 'YYYY-MM-DD Hh24:MI:SS') from dual;
TO_CHAR(TRUNC(SYSDA
-------------------
2017-06-04 00:00:00
If you want data up to the start of that fourth day, i.e. up to 23:59:59 on the 3rd, you can look for values less than midnight on the 4th:
select * from test.purchase
where create_ts >= trunc(sysdate, 'MM')
and create_ts < trunc(sysdate, 'MM') + 3;
You could potentially use between, but as that is inclusive you would need to specify the absolute latest time on the 3rd - checking whether the column is a date or a timestamp, which might change, and can be a little confusing. If you used between trunc(sysdate, 'MM') and trunc(sysdate, 'MM') + 3 then you would include any records at exactly midnight on the 4th, which isn't what you want. I find using >= and < clearer and less ambiguous, even if it is a little more typing.
If the column is actually a timestamp then you can cast the calculated dates to timestamp too, and/or an use interval for the upper bound:
select * from test.purchase
where create_ts >= cast(trunc(sysdate, 'MM') as timestamp)
and create_ts < cast(trunc(sysdate, 'MM') + 3 as timestamp);
... or:
...
and create_ts < cast(trunc(sysdate, 'MM') as timestamp) + interval '3' day;

Oracle Add 1 hour in SQL

I am just trying to add 1 hour to a value, it is kind of complicated on where and why i am doing this but basically i just need to query something like this
select DATE_ADD(hh,1,'2014-10-15 03:30:00 pm') from dual
I keep reading old articles that say to use dateAdd or date_add but I keep getting invalid identifier errors.
select sysdate + 1/24 from dual;
sysdate is a function without arguments which returns DATE type
+ 1/24 adds 1 hour to a date
select to_char(to_date('2014-10-15 03:30:00 pm', 'YYYY-MM-DD HH:MI:SS pm') + 1/24, 'YYYY-MM-DD HH:MI:SS pm') from dual;
Use an interval:
select some_date_column + interval '1' hour
from your_table;
You can use INTERVAL type or just add calculated number value - "1" is equal "1 day".
first way:
select date_column + INTERVAL '0 01:00:00' DAY TO SECOND from dual;
second way:
select date_column + 1/24 from dual;
First way is more convenient when you need to add a complicated value - for example, "1 day 3 hours 25 minutes 49 seconds".
See also: http://www.oracle-base.com/articles/misc/oracle-dates-timestamps-and-intervals.php
Also you have to remember that oracle have two interval types - DAY TO SECOND and YEAR TO MONTH.
As for me, one interval type would be better, but I hope people in oracle knows, what they do ;)
Old way:
SELECT DATE_COLUMN + 1 is adding a day
SELECT DATE_COLUMN + N /24 to add hour(s) - N being number of hours
SELECT DATE_COLUMN + N /1440 to add minute(s) - N being number of minutes
SELECT DATE_COLUMN + N /86400 to add second(s) - N being number of seconds
Using INTERVAL:
SELECT DATE_COLUMN + INTERVAL 'N' HOUR or MINUTE or SECOND - N being a number of hours or minutes or seconds.
To add/subtract from a DATE, you have 2 options :
Method #1 :
The easiest way is to use + and - to add/subtract days, hours, minutes, seconds, etc.. from a DATE, and ADD_MONTHS() function to add/subtract months and years from a DATE. Why ? That's because from days, you can get hours and any smaller unit (1 hour = 1/24 days), (1 minute = 1/1440 days), etc... But you cannot get months and years, as that depends on the month and year themselves, hence ADD_MONTHS() and no add_years(), because from months, you can get years (1 year = 12 months).
Let's try them :
SELECT TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints current date: 19-OCT-2019 20:42:02
SELECT TO_CHAR((SYSDATE + 1/24), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 hour: 19-OCT-2019 21:42:02
SELECT TO_CHAR((SYSDATE + 1/1440), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 minute: 19-OCT-2019 20:43:02
SELECT TO_CHAR((SYSDATE + 1/86400), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 second: 19-OCT-2019 20:42:03
-- Same goes for subtraction.
SELECT SYSDATE FROM dual; -- prints current date: 19-OCT-19
SELECT ADD_MONTHS(SYSDATE, 1) FROM dual; -- prints date + 1 month: 19-NOV-19
SELECT ADD_MONTHS(SYSDATE, 12) FROM dual; -- prints date + 1 year: 19-OCT-20
SELECT ADD_MONTHS(SYSDATE, -3) FROM dual; -- prints date - 3 months: 19-JUL-19
Method #2 : Using INTERVALs, you can or subtract an interval (duration) from a date easily. More than that, you can combine to add or subtract multiple units at once (e.g 5 hours and 6 minutes, etc..)
Examples :
SELECT TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints current date: 19-OCT-2019 21:34:15
SELECT TO_CHAR((SYSDATE + INTERVAL '1' HOUR), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 hour: 19-OCT-2019 22:34:15
SELECT TO_CHAR((SYSDATE + INTERVAL '1' MINUTE), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 minute: 19-OCT-2019 21:35:15
SELECT TO_CHAR((SYSDATE + INTERVAL '1' SECOND), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 second: 19-OCT-2019 21:34:16
SELECT TO_CHAR((SYSDATE + INTERVAL '01:05:00' HOUR TO SECOND), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 1 hour and 5 minutes: 19-OCT-2019 22:39:15
SELECT TO_CHAR((SYSDATE + INTERVAL '3 01' DAY TO HOUR), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date + 3 days and 1 hour: 22-OCT-2019 22:34:15
SELECT TO_CHAR((SYSDATE - INTERVAL '10-3' YEAR TO MONTH), 'DD-MON-YYYY HH24:MI:SS') FROM dual; -- prints date - 10 years and 3 months: 19-JUL-2009 21:34:15
The calculation is simple
if you want to add 1 hour in the date .
every day have 24 hour , you can add .
select sysdate + 1/24 from dual;
if you want 1 day to add
select sysdate + 24/24 from dual;
or
select sysdate + 1 from dual;
same as for 2, 3 , 4 day
For static date you have the answer below.