Want to run query from specific time of today to last n hours - oracle

Hi I want to run a query which extracts data from 7:00 am in the morning to 3:00 pm yesterday.
I run this query in afternoon.
Below query extracts data from time I run the query. I want the data from 7:00 am and backwards.
select *
from NOTES
where creation_date >= sysdate- interval '17:15' hour to minute
I would appreciate any help.

Try this in Oracle:
SELECT *
FROM NOTES
WHERE creation_date BETWEEN to_timestamp(to_char(sysdate) || ' 00:00:00', 'dd-Mon-yy hh24:mi:ss') - interval '9' hour
AND to_timestamp(to_char(sysdate) || ' 00:00:00', 'dd-Mon-yy hh24:mi:ss') + interval '7' hour;
Try this in MySQL:
SELECT *
FROM NOTES
WHERE creation_date >= (concat(current_date(), ' 00:00:00') - interval '09:00' hour)
AND creation_date <= (concat(current_date(), ' 00:00:00') + interval '07:00' hour);

Try this as optimal
For Oracle
SELECT *
FROM NOTES
WHERE creation_date BETWEEN trunc(sysdate) - INTERVAL '9' HOUR
AND trunc(curdate) + INTERVAL '7' HOUR;
For MySQL
SELECT *
FROM NOTES
WHERE creation_date BETWEEN curdate() - INTERVAL 9 HOUR
AND curdate() + INTERVAL 7 HOUR;
If you need detail info - just ask.

Related

date format picture ends before converting entire input string in Oracle

I have a PD_HEAT_DATA table with HEATID and HEATDEPARTURE_ACT columns. Data type of HEATDEPARTURE column is VARCHAR2 and it holds timestamps in the format 2019-07-28 23:11:11,359.
My requirement is to retrieve the records from PD_HEAT_DATA table between 6 AM of today and 6 AM of next day.
Sample Data:
HeatID HEATDEPARTURE_ACT
0001024002 2019-07-29 00:46:42,115
0001024003 2019-07-29 06:46:42,115
0001024004 2019-07-29 23:46:42,115
0001024003 2019-07-30 00:06:42,115
0001024004 2019-07-30 04:46:42,115
I have tried following code but it is not giving desired result:
select heatid, HEATDEPARTURE_ACT from hd_heat_data where to_date(HEATDEPARTURE_ACT, 'YYYY-MM-DD HH24:MI:SS') >= trunc(sysdate
-1) + 6/24 and
to_date(HEATDEPARTURE_ACT, 'YYYY-MM-DD HH24:MI:SS') < trunc(sysdate) + 6/24
I have tried following code but it is not giving desired result:
select heatid, HEATDEPARTURE_ACT from hd_heat_data where to_date(HEATDEPARTURE_ACT, 'YYYY-MM-DD HH24:MI:SS') >= trunc(sysdate
-1) + 6/24 and
to_date(HEATDEPARTURE_ACT, 'YYYY-MM-DD HH24:MI:SS') < trunc(sysdate) + 6/24
You have fractional seconds at the end of your HEATDEPARTURE_ACT strings which you need to trim off prior to converting the string to a date:
select heatid, HEATDEPARTURE_ACT
from hd_heat_data
where TO_DATE(REGEXP_SUBSTR(HEATDEPARTURE_ACT, '[^,]*'),
'YYYY-MM-DD HH24:MI:SS') BETWEEN trunc(sysdate-1) + INTERVAL '6' HOUR
AND trunc(sysdate) + INTERVAL '6' HOUR - INTERVAL '1' SECOND
dbfiddle here
(Note that I altered the dates in the fiddle data so results would be produced)
You need to change your format provided in TO_TIMESTAMP as TO_TIMESTAMP(HEATDEPARTURE_ACT, 'YYYY-MM-DD HH24:MI:SS,FF')
SELECT
HEATID,
HEATDEPARTURE_ACT
FROM
HD_HEAT_DATA
WHERE
TO_TIMESTAMP(HEATDEPARTURE_ACT, 'YYYY-MM-DD HH24:MI:SS,FF')
BETWEEN TRUNC(SYSDATE - 1) + INTERVAL '6' HOUR AND TRUNC(SYSDATE) +
INTERVAL '6' HOUR - INTERVAL '1' SECOND
See the demo of reproduction of the issue and resolution, HERE
Cheers!!

How to filter particular time period in oracle

I have a date and time column(Login_time) in this format '5/23/2018 3:35:18 PM'. I want to filter rows with August month and time period of 6.30 to 7.30. I am able to filter august month using Login_time >= to_date('08/1/2018','MM/DD/YYYY') and Login_time >= to_date('08/31/2018','MM/DD/YYYY') but now I want rows only between 6.30 am to 7.30 am.
Be careful with date/time ranges. You'd usually want to include the start time and exclude an end time, e.g. all rows from 2018-08-01 until before 2018-09-01, thus including the whole last day, no matter how close to midnight. Here is the whole query:
select *
from mytable
where login_time >= date '2018-08-01'
and login_time < date '2018-09-01'
and to_char(login_time, 'hh24:mi') >= '06:30'
and to_char(login_time, 'hh24:mi') < '07:31';
You could format the time portion of column to a string, and then compare it lexichograpically:
TO_CHAR(login_time, 'HH24:MI:SS') BETWEEN '06:30:00' AND '07:30:00'
You simply include the time:
Login_time >= to_date('08/01/2018 06:30:00','MM/DD/YYYY HH24:MI:SS')
and Login_time <= to_date('08/31/2018 07:30:59','MM/DD/YYYY HH24:MI:SS')
and to_char(login_time, 'hh24:mi:ss') >= '06:30:00'
and to_char(login_time, 'hh24:mi:ss') <= '07:30:59'
or
EXTRACT(MONTH FROM CAST(Login_time AS TIMESTAMP)) = 8
and to_char(login_time, 'fmSSSSS') between 6*60*60 + 30*60 AND 7*60*60 + 30*60
I've taken a different approach to the "between 6:30 AM and 7:30 AM" requirement. In this answer, I subtract 30 minutes, then check if the hour value is either 6 or 7. I chose this approach as a variation to string comparison. I don't know if it performs better but it's an alternate approach. The casting to timestamp is necessary to extract the hour value.
WHERE trunc(login_time) BETWEEN to_date('8/1/2018', 'mm/dd/yyyy') AND to_date('8/31/2018', 'mm/dd/yyyy')
AND extract(hour FROM cast(login_time-(30/60/24) as timestamp)) IN (6,7)
If you are always going to be querying an entire month, this could be shortened to
WHERE trunc(login_time, 'MONTH') = to_date('8/1/2018', 'mm/dd/yyyy')
AND extract(hour FROM cast(login_time-(30/60/24) as timestamp)) IN (6,7)

Using "today" and "two days before" in date with Oracle

I have the following WHEREclause in a query:
SELECT ...
FROM ...
WHERE IMPORT_DATE between
to_date('2018-03-16 00:00:00', 'yyyy-mm-dd hh24:mi:ss') and
to_date('2018-03-16 23:59:59', 'yyyy-mm-dd hh24:mi:ss')
And I would like to write two new queries:
One with this same clause but using "today" instead of "2018-03-16".
Another with the same clause but using "the day before yesterday" (today - 2) instead of "2018-03-16".
How can I do this in Oracle?
As Oracle has no real DATE data type and always includes a time, it's usually better to not use between for conditions like that, but to use >= together with < compared to midnight the next day.
To find the rows from "today" use:
SELECT ...
FROM ...
WHERE import_date >= trunc(sysdate)
AND import_date < trunc(sysdate) + 1;
or:
SELECT ...
FROM ...
WHERE import_date >= trunc(sysdate) - 2
AND import_date < (trunc(sysdate) - 2) + 1;
The parentheses aren't really required in the second expression, they are just there to document that it's the same expression as the first one.
select trunc(sysdate) from dual;
Returns today's date without any time
select trunc(sysdate) - interval '2' day from dual;
Returns the day 2 days before today without time.
You can also use month, hour, year etc instead of day.

Subtracting/Adding to a Where clause timestamp condition

I'm attempting to speed up a timestamp comparison query by restricting the query to 30 minutes before and after the timestamp in question. This is the format I'm using:
Causedat
-----
11-NOV-15 10.20.58.000000000 AM
11-NOV-15 10.19.41.877000000 AM
10-NOV-15 11.01.40.000000000 AM
10-NOV-15 11.00.50.460000000 AM
05-NOV-15 01.53.30.966000000 PM
05-NOV-15 01.47.31.000000000 PM
What I'm trying to do is write a condition where i'll tell the system only to look for dates in the system that are +-00:30:00.000000000 (thirty minutes) from the Causedat date in the future or past from that time.
I've seen that for example, SYSDATE - SYSTIMESTAMP is a legitimate calculation. Is it possible to do something similar to this like this:
WHERE search.date >= (Causedat = Causedat - '000000000 00:30:00.000000000')
AND search.date <= (Causedat = Causedat + '000000000 00:30:00.000000000')
Please assume the date i'm searching and Causedat are in the same (timestamp) format for this question.
Thank you for any light you may be able to shine on the problem for me.
You can add an interval to a timestamp; you can read about datetime and interval arithmetic. There are conversion functions to go from a variable to an interval, but with known fixed values you can use an interval literal here. You can use the full string you have:
where search_date >= causedat - interval '000000000 00:30:00.000000000' day to second
and search_date <= causedat + interval '000000000 00:30:00.000000000' day to second;
Or just the non-zero part:
where search_date >= causedat - interval '30' minute
and search_date <= causedat + interval '30' minute;
Trivial demo of how these evaluate:
select systimestamp,
systimestamp - interval '000000000 00:30:00.000000000' day to second as minus_30,
systimestamp + interval '000000000 00:30:00.000000000' day to second as plus_30
from dual;
SYSTIMESTAMP MINUS_30 PLUS_30
----------------------------------- ----------------------------------- -----------------------------------
18-NOV-15 11.39.09.597473000 +00:00 18-NOV-15 11.09.09.597473000 +00:00 18-NOV-15 12.09.09.597473000 +00:00
select systimestamp,
systimestamp - interval '30' minute as minus_30,
systimestamp + interval '30' minute as plus_30
from dual;
SYSTIMESTAMP MINUS_30 PLUS_30
----------------------------------- ----------------------------------- -----------------------------------
18-NOV-15 11.39.09.653809000 +00:00 18-NOV-15 11.09.09.653809000 +00:00 18-NOV-15 12.09.09.653809000 +00:00
Direct arithmetic on date time column with required interval value.
WHERE search.date
BETWEEN Causedat - INTERVAL '30' MINUTE
AND Causedat + INTERVAL '30' MINUTE
I just went through the question. I have provided a simple example to illustrate how we can achieve this.
SELECT A.DT
FROM
( SELECT SYSTIMESTAMP - INTERVAL '60' MINUTE AS DT FROM DUAL
UNION
SELECT SYSTIMESTAMP - INTERVAL '30' MINUTE AS DT FROM DUAL
UNION
SELECT SYSTIMESTAMP AS DT FROM DUAL
UNION
SELECT SYSTIMESTAMP + INTERVAL '30' MINUTE AS DT FROM DUAL
UNION
SELECT SYSTIMESTAMP + INTERVAL '60' MINUTE AS DT FROM DUAL
)A
WHERE A.DT BETWEEN (SYSTIMESTAMP - INTERVAL '30' MINUTE) AND (SYSTIMESTAMP + INTERVAL '30' MINUTE);
Let me know if this helps.

Oracle sysdate flexible date

I worked this statement out
SELECT to_date('30.06.2016', 'dd.mm.yyyy') - (LEVEL-1) DATUM
FROM DUAL
CONNECT BY LEVEL <= 366;
which gives me all dates from 30.06.2016 till 366 days in the past.
So far so good.
What I need to add is that to_date('30.06.2016') is more flexible..
What I mean I always want it to use the last day of June in sysdate + 1 year.
In this case we have 2015 at the moment - so we have 30.06.2016.
If we had 2016 I need it to use 30.06.2017.
If we had 2017 I need it to use 30.06.2018.
..
..
Thanks for your help.
EDIT Solution:
SELECT last_day(add_months(to_date('01.06.' || to_char(sysdate, 'YYYY'), 'dd.mm.yyyy'),12)) - (LEVEL-1) DATUM
FROM DUAL
CONNECT BY LEVEL <= 366
If you want 366 days worth of dates:
SELECT TRUNC( SYSDATE, 'YEAR' ) + INTERVAL '18' MONTH - LEVEL AS DATUM
FROM DUAL
CONNECT BY LEVEL <= 366;
Or if you want a year's worth (365 days or 366 days in a leap year) of dates (1st July this year to 30th June next year):
SELECT TRUNC( SYSDATE, 'YEAR' ) + INTERVAL '18' MONTH - LEVEL AS DATUM
FROM DUAL
CONNECT BY TRUNC( SYSDATE, 'YEAR' ) + INTERVAL '18' MONTH - LEVEL >= TRUNC( SYSDATE, 'YEAR' ) + INTERVAL '6' MONTH;
Is your same code, but get from sysdate the year, using to_char:
select to_date('30.06.'||(to_char(sysdate,'yyyy')+1),'dd.mm.yyyy') from dual;
Here's the steps:
Truncate sysdate to the year, using Trunc().
Add 18 months, using Add_Months().
Subtract one day.

Resources