last day/time of month - sql

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;

Related

Bring data from the last day of the previous month beyond

I'm using Oracle SQL Developer and I would like to make a SELECT that brings all the products sold from the last day of the previous month (but only products sold from 4 pm on the last day of the previous month) to the current day (only until 8 am of the current day).
For example, today is 7/21/2022. If I run this query today, it should bring data from:
06/30/2022 above 16:00hrs -> 07/21/2022 until 08:00hrs
You can use TRUNC(value, 'MM') to find midnight of the 1st day of the current month and then subtract 8 hours to find the start of the range and then use TRUNC(value) to find midnight of today and add 8 hours to find the end of the range:
SELECT *
FROM table_name
WHERE date_column >= TRUNC(SYSDATE, 'MM') - INTERVAL '8' HOUR
AND date_column <= TRUNC(SYSDATE) + INTERVAL '8' HOUR;
You can use TRUNC to get to the first day of a date's month. Then subtract one day and add sixteen hours. And it's again TRUNC that you use to get back to the beginning of a day (midnight) to which you can add eight hours.
select *
from mytable
where dt >= trunc(sysdate, 'mm') - interval '1' day + interval '16' hour
and dt < trunc(sysdate, 'dd') + interval '8' hour
order by dt;

Get the timestamp of the last and first day of a month in postgresSQL

I am currently trying to figure out the equivalent functions in PostgresSQL for the below MariaDB functions:
SELECT
CONCAT(DATE_ADD(DATE_ADD(LAST_DAY('2021-02-15 00:00:00'),INTERVAL 1 DAY),INTERVAL -1 MONTH), ' ', '00:00:00') AS first_day_of_the_month,
CONCAT(LAST_DAY('2021-02-15 23:59:59'), ' ' ,'23:59:59') AS last_day_of_the_month;
Expected Result:
first_day_of_the_month | last_day_of_the_month
------------------------|-------------------------------
2021-02-01 00:00:00 | 2021-02-28 23:59:59
I want to get the last day and the first day of the month of a certain date including the time 00:00:00 for the first day and 23:549:59 for the last day.
So far I am comming close to the expected result with these queries:
SELECT
(date_trunc('MONTH', '2021-02-15 00:00:00'::TIMESTAMP) + INTERVAL '1 MONTH - 1 day')::TIMESTAMP
+ '1 days'::INTERVAL - '1 months'::INTERVAL AS first_day_of_the_month,
(date_trunc('MONTH', '2021-02-15 23:59:59'::TIMESTAMP) + INTERVAL '1 MONTH - 1 day')::TIMESTAMP AS last_day_of_the_month;
However, as you can see in the DB-Fiddle for the last_day_of_the_month I am getting 00:00:00 instead of 23:59:59.
How do I need to change the query to get the correct timestamp?
demo:db<>fiddle
/* Option 1: Certain Date */
SELECT
date_trunc('month', timestamp '2021-02-15 00:00:00') AS first_timestamp,
date_trunc('month', timestamp '2021-02-15 23:59:59') + interval '1 month - 1 second' AS last_timestamp;
/* Option 2: Current_date */
SELECT
date_trunc('month', current_date)::timestamp AS first_timestamp,
date_trunc('month', current_date)::timestamp + interval '1 month - 1 second' AS last_timestamp;
First timestamp of month
date_trunc('month', ...) normalizes the date to the first possible timestamp of the month. So it returns 00:00:00 of the first day of the month
Last timestamp of month
If you add a month to the previous result, you get the first day/timestamp (00:00:00) of the next month. If you subtract a day from this, you get the last day of the current month. Of course, you can subtract just a second to get 23:59:59 of the last day of the month as you expected.
For the first day of the month:
date_trunc('month', the_date_column)
For the last day:
date_trunc('month', the_date_column) + interval '1 month' - interval '1 day'
Or if you prefer:
date_trunc('month', date) + interval '1 month - 1 day'
If you really one one second from midnight on the last day, replace day with second in the logic. I don't recommend that. In fact, if you want to define a range of date, define an open range and just use the first day of the next month. Then you can learn about tsrange which builds this into the language.

import data between specific times from consecutive days

In BIRT Report (which executes query for 10 minutes automatically - 24x7), I would like to report data of datatype "Timestamp", which I import from a table in oracle databank using query. Let's say I have a table with name "table 1". Table 1 contains a column with name "column1" of datatype timestamp. The data in column1 is from a machine which runs continuously (24x7 - 365 days).
Everyday in the report, I would like to present only 24 hours data, which is between 05:30:00 (present day) and 05:30:00 (next day).
SELECT column1 from table 1
WHERE coulmn1 = SYSDATE - INTERVAL '24' hour;
Extracting data of last 24 hours or days or months is easy, but how to define a logic in where statement, which takes the actual systemtime as a reference and provides data between 05:30 (present day) and 05:30 (next day).
For Example:
The automatic execution of query at 01:00:00 (or 1 AM) should show the data from previous day (05:30:00) to present (01:00:00)
The automatic executin of query at 08:00:00 (or 8 AM) should show the data from actual day (05:30:00 to 08:00:00).
Any help how to define a logic in where statement will be appreciated.
Use TRUNC(SYSDATE) to trunate it back to midnight and then add an INTERVAL:
SELECT column1
FROM table1
WHERE column1 >= TRUNC( SYSDATE ) + INTERVAL '0 05:30' DAY TO MINUTE
AND column1 < TRUNC( SYSDATE ) + INTERVAL '1 05:30' DAY TO MINUTE;
If you want to handle the case when the SYSDATE is before 05:30 then:
SELECT column1
FROM table1
WHERE column1 >= TRUNC( SYSDATE - INTERVAL '05:30' HOUR TO MINUTE )
+ INTERVAL '0 05:30' DAY TO MINUTE
AND column1 < TRUNC( SYSDATE - INTERVAL '05:30' HOUR TO MINUTE )
+ INTERVAL '1 05:30' DAY TO MINUTE;
And if you do not want to show future times then:
SELECT column1
FROM table1
WHERE column1 >= TRUNC( SYSDATE - INTERVAL '05:30' HOUR TO MINUTE )
+ INTERVAL '0 05:30' DAY TO MINUTE
AND column1 <= SYSTIMESTAMP;

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.