Usecase: Query to select the records for a whole day and it should run regularly.
This is my query.
Select to_char(in_date + interval '12' hour, 'DD-MON-YYYY HH24:MI:SS')
from my_table
where incoming_date > sysdate-2 and incoming_date < sysdate
I need to select yesterday's data only. Because of the conversion in the select statement I got today's data also. How do I select only yesterday's data? My DB is in UTC+7.00 standard. I need to display it in local standard so that I did a conversion in select statement. And how do I display only yesterday's data?
I'm stuck. Please help me
To get all data from yesterday you should use
SELECT TO_CHAR(IN_DATE + INTERVAL '12' HOUR, 'DD-MON-YYYY HH24:MI:SS')
FROM MY_TABLE
WHERE INCOMING_DATE BETWEEN TRUNC(SYSDATE) - INTERVAL '1' DAY
AND TRUNC(SYSDATE) - INTERVAL '1' SECOND
If, for example, SYSDATE is 05-NOV-2017 18:56:35, the time interval used in the BETWEEN comparison will be from 04-NOV-2017 00:00:00 to 04-NOV-2017 23:59:59. BETWEEN comparisons are inclusive of both endpoints so this will only return data with an INCOMING_DATE of sometime on 04-NOV-2017, in this example.
Best of luck.
only to get the
yesterday's data
make your
WHERE condition as
incoming_date between trunc(sysdate) - interval '1' day and trunc(sysdate) - interval '1' second
My DB is in UTC+7.00 standard. I need to display it in local standard so that I did a conversion in select statement.
Using a magic value (INTERVAL '12' HOUR) does not describe what it means or the assumptions you made when chosing that value. Instead you can better describe the process by using FROM_TS( timestampvalue, timezonestring ) to convert the value from a TIMESTAMP to a TIMESTAMP WITH TIME ZONE data type and then use AT LOCAL TIME to convert it to the local time. Then if you have daylight savings time or port the query to another international location then it will still display in the current local time. Like this:
SELECT TO_CHAR(
FROM_TZ( CAST( in_date AS TIMESTAMP ), '+07:00' ) AT LOCAL TIME,
'DD-MON-YYYY HH24:MI:SS'
)
FROM my_table
WHERE incoming_date >= TRUNC( SYSDATE ) - INTERVAL '1' DAY
AND incoming_date < TRUNC( SYSDATE )
And how do I display only yesterday's data?
TRUNC( SYSDATE ) will truncate today's date back to midnight. To get yesterday's data then you can get values that are greater or equal to TRUNC( SYSDATE ) - INTERVAL '1' DAY (one day before midnight today) and also less than TRUNC( SYSDATE ) (midnight today).
I'm not exactly sure I get your question, but I think I can explain some stuff.
I'll be assuming your table is a bit like this:
date_added | some_data | some_more_data
------------|-----------|----------------
date | data1 | data2
As I understand your goal is to fetch all the rows that were added to a table the day before the query is run using a select statement. but your current attempt fails at doing so by also returning today's results.
Here is what's happening (I think):
SYSDATE doesn't just give you the current date, it also gives you the time. You can see that for your self by simply altering your current session and setting the date/time format to one that includes both time and date
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY HH24:MI:SS';
The reason why you would be getting today's rows is simple, your query is asking for all the rows who's date_added field is between right now and right now - 24 hours. Not today and today - 24 hours.
So what is the solution?
Use the TRUNC function to trim the SYSDATE to the day instead!
https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions201.htm
SELECT
T.*
FROM
MY_TABLE T
WHERE
T.DATE_ADDED BETWEEN (TRUNC(SYSDATE,'day') - 1) AND TRUNC(SYSDATE,'day');
As you did mention timezones being a thing keep in mind that SYSDATE returns the date on the server itself and not your computer's.
More on that here: https://stackoverflow.com/a/17925834/7655979
Usually I compare the date only using Trunc.
WHERE trunc(incoming_date) = trunc(sysdate-1)
Related
I have these varchar : 20211026231735.
So I would like a query to substract actual sysdate to that date and convert the substraction to DAY HOURS AND SECONDS.
select TO_CHAR(SYSDATE,'YYYYMMDDHH24MISS') - start_time from TABLEA where job_name='jOB_AA_BB';
I get 4220.
Any help please? Thanks
When you do datetime arithmetic with the DATE datatype, you get back a NUMBER of days. To get an INTERVAL you can subtract two TIMESTAMPs. You don't say what the data type is for start_time, but you might get away with this:
select localtimestamp - start_time
from tablea where job_name='jOB_AA_BB';
LOCALTIMESTAMP gives you a TIMESTAMP value in the current session time zone. There's also CURRENT_TIMESTAMP, which give you the same thing in a TIMESTAMP WITH TIME ZONE and SYSTIMESTAMP that gives you the database time in TIMESTAMP WITH TIME ZONE. You may need to convert your start_time to avoid time zone differences, if any.
You can us the function numtodsinterval to convert the results of date arithmetic to an interval. If necessary then use extract to pull out the needed components.
with tablea(job_name, start_time) as
(select 'jOB_AA_BB','20211026231735' from dual)
select numtodsinterval((SYSDATE - to_date( start_time,'yyyymmddhh24miss')),'hour') date_diff
from tablea where job_name='jOB_AA_BB' ;
with tablea(job_name, start_time) as
(select 'jOB_AA_BB','20211026231735' from dual)
select extract (hour from date_diff) || ':' || extract (minute from date_diff)
from (
select numtodsinterval((sysdate - to_date( start_time,'yyyymmddhh24miss')),'day') date_diff
from tablea where job_name='jOB_AA_BB'
);
NOTE: I am not sure how you got any result, other than an error, as your query winds up as a string - a string. You should not convert sysdate to a string but your string to a date (better yet store it as the proper data type - date).
You can convert the value to a date (rather than converting SYSDATE to a string) and then subtract and explicitly return the value as an INTERVAL DAY TO SECOND type:
SELECT (SYSDATE - TO_DATE('20211026231735', 'YYYYMMDDHH24MISS')) DAY TO SECOND
FROM DUAL;
Or, for your table:
SELECT (SYSDATE - TO_DATE(start_time,'YYYYMMDDHH24MISS')) DAY(5) TO SECOND
FROM TABLEA
WHERE job_name='jOB_AA_BB';
db<>fiddle here
I'm having trouble with filtering a date and time for anything two hours before and sooner. I tried this:
SELECT *
FROM
table
where
date >= sysdate - 1
AND
TO_DATE( Time, 'HH24:MI:SS' ) >= TO_DATE( sysdate, 'HH24:MI:SS' ) - 2
But I'm getting an inconsistent type error which is what I thought I was handling with the TO_DATE() function but I guess not.
sysdate is already a date (and time), so TO_DATE( sysdate, 'HH24:MI:SS' ) doesn't make any sense.
You didn't provide your data types for your date and time columns in table, so I'm going to assume they're both varchar2(10) with formats MM/DD/YYYY and HH24:MI:SS respectively.
I'm also going to go ahead and change your example table and column names, since they're invalid names to use in a real query.
-- example data
with my_table as (select '06/13/2019' as date_column, '09:40:34' as time_column from dual)
-- your query
SELECT *
FROM
my_table
where
to_date(date_column || ' ' || time_column, 'MM/DD/YYYY HH24:MI:SS') >= sysdate - 2/24
What I'm doing here is to combine your date and time strings into one date-time string, then converting it to an Oracle date type (actually date+time). Then we compare it to sysdate - 2/24, which says to take the current time and subtract 2/24ths of a day, which is 2 hours.
For this example, you might need to change the example data date_column and time_column values to something from the past 2 hours, depending on when you run this and what time zone you're in.
so I have a table called Value. I am trying to derive the Value for the last hour (HR --> Timestamp(4) with TIME ZONE ) so that I can use it in a conditional statement in this Stored Procedure that I'm building. However, when i try the following, Oracle only returns a Date (01-Jan-19) rather than the previous hour (01-Jan-19 01.00.00.00000000 AM UTC). What am I doing wrong?
select hr
, hr - (1/24) as Converted
from value;
If I try the following, I return '31-DEC-16 12.00.00.000000000 AM' as the value for 'Converted' (no matter what the value for HR is):
select hr
, to_timestamp(hr - (1/24)) as converted
from value;
Which ultimately will be used as the definition of a variable in my stored procedure:
select max(value)
into v_Previous_hour
from value
where hr = hr - (1/24);
Am I missing something here? Thanks in advance.
Try this:
select hr
, cast( hr - (1/24) as timestamp) as Converted
from value;
Also, the query below is not going to do what you think it is.
select max(value)
into v_Previous_hour
from value
where hr = hr - (1/24);
Or you could use INTERVAL:
SELECT TO_CHAR(HR) AS HR,
TO_CHAR(CAST(HR - INTERVAL '1' HOUR - INTERVAL '0.233' SECOND AS TIMESTAMP(4) WITH TIME ZONE)) AS HR_MINUS_ONE_HOUR
FROM VAL;
(Here I subtracted an additional 0.233 seconds just to make sure we were dealing with timestamps, per #AlexPoole's comment on #OldProgrammer's answer).
SQLFiddle here
Oracle only returns a Date (01-Jan-19)
A date still has a time, your client just isn't showing it to you. You can use to_char() to display it explicitly:
select to_char(hr - (1/24), 'YYYY-MM-DD HH24:MI:SS') from ...
It is a date because [that's the result of timestamp - number] arithmetic, and the timestamp is implicitly converted to a date before the subtraction. But you are losing both the fractional seconds and the time zone from your original value. Even if you cast back to a plain timestamp that information isn't recovered, and if you cast back to a timestamp with time zone it imolicitly picks up the current session's time zone, so won't necessarily match.
To keep both you can do what you suggested in your answer, or
select hr - interval '1' hour from ...
In your procedure, declare a variable of the same data type, e.g. (as an nonymous block):
declare
l_hr value.hr%type;
begin
select hr - interval '1' hour
into l_hr
from value
where ... ;
...
end;
Don't be tempted to store or manipulate the value as a string, keep it as its origial data type. It will be easieer to work with, safer and more efficient.
Have a look at this table Matrix of Datetime Arithmetic
When you perform {TIMESTAMP WITH TIME ZONE} - {NUMERIC} then you get DATE value, i.e. you loose the time zone information.
Better use INTERVAL, e.g. hr - INTERVAL '1' HOUR or hr - NUMTODSINTERVAL(1, 'HOUR')
Anyway, I don't understand your question. If you ask "How to grab the previous hour of a timestamp(4) with TIMEZONE column?" then my answer would be
SELECT
EXTRACT(HOUR FROM hr - INTERVAL '1' HOUR) AS Solution_1
TO_CHAR(hr - INTERVAL '1' HOUR, 'HH24') AS Solution_2
FROM ...
Note, solution EXTRACT(HOUR FROM hr - INTERVAL '1' HOUR) always returns the hour of UTC time, whereas TO_CHAR(hr - INTERVAL '1' HOUR, 'HH24') returns hour from the stored time zone.
After 2 hours of hairpulling (and ironically after OldProgrammer was nice enough to provide me with an answer), I found a workaround:
select hr
, hr - numtodsinterval(1, 'hour') as converted
from value;
I am getting into Oracle database. I came across the TRUNC(DATE, [FMT]) function. I am not really clear on it except it seems to return the beginning value of some sort?
Can somebody educate me on it? When or what would it be used for at work, or why somebody might want to use the function?
Try this query to know when it might be usefull:
ALTER SESSION SET NLS_DATE_FORMAT = 'yyyy-mm-dd hh24:mi:ss';
select sysdate,
trunc( sysdate, 'mi' ) As beginning_of_current_minute,
trunc( sysdate, 'mi' ) As beginning_of_current_hour,
trunc( sysdate, 'dd' ) As beginning_of_current_day,
trunc( sysdate, 'iw' ) As beginning_of_current_week,
trunc( sysdate, 'mm' ) As beginning_of_current_month,
trunc( sysdate, 'q' ) As beginning_of_current_Quarter,
trunc( sysdate, 'y' ) As beginning_of_current_Year
FROM dual;
An example - you want to get all orders starting from the beginning of the current week:
SELECT *
FROM ORDERS
WHERE order_date >= trunc( sysdate, 'iw' )
A real world example would be if you wanted to aggregate results from a table by year. You could use the TRUNC function like this:
SELECT TRUNC(my_date, 'YEAR') the_year, count(*)
FROM some_table
GROUP BY TRUNC(my_date, 'YEAR');
...which would return a set of results with the first column the date truncated to the beginning of the year and the second column a count of all the records with dates within that year.
the_year, count(*)
_________________
01-JAN-12, 543
01-JAN-13, 1268
01-JAN-14, 1134
01-JAN-15, 1765
There are obviously other ways to achieve the same thing, but this is a real world example of how you might use TRUNC.
Another might be if you are comparing dates and you only want to use a certain degree of precision. If you have a timestamp column and you want all the records for today, you could select based on a range where the timestamp is greater than midnight yesterday and less than midnight today, or you could select where the timestamp, truncated to the DATE, is equal to today.
https://docs.oracle.com/cd/E29805_01/server.230/es_eql/src/cdfp_analytics_lang_trunc.html
Another thing it is useful for is to get the time component of the current day. I use an expression like this all the time:
SELECT sysdate - trunc(sysdate) AS TodaysTime FROM DUAL
Because the system date is stored in a decimal format (e.g. sysdate = 42651.2426897456) and the integer value corresponds to midnight, I can use the above statement to get only the decimal portion (e.g. TodaysTime = 0.2426897456, or just before 6 AM).
There may be easier ways to do this, but in my applications this has been the easiest as I frequently need to work with only the day's time component.
How I can to see last 5 mins record before the current time through sql query how i can do this.
The format of time stamp is
03/25/2014 14:00:00
I used this query for the same
SELECT Time stamp FROM TABLE
WHERE S >1 AND SUBSTRING((Time stamp,15,2)-5)
is this fine of any other way to do the same
If you are using MySQL and your timestamp column is of data type datetime you can do
SELECT Timestamp
FROM your_table
WHERE Timestamp >= now() - interval 5 minute
If your timestamp is a date column, you can simply do:
select t.*
from table t
where t.timestamp >= sysdate - 5/(24*60)
Things are a bit more interesting if timestamp is a character column. Then you need to translate it to a date/time:
select t.*
from table t
where to_date(t.timestamp, 'MM/DD/YYYY HH24:MI:SS') >= sysdate - 5/(24*60)
select *
from the_table
where timestamp_column <= timestamp '2014-03-25 14:00:00' - interval '5' minute;
This assumes that timestamp_column is defined with the data type timestamp.
If it isn't you should stop now and re-define your table to use the correct data type.
The expression timestamp '2014-03-25 14:00:00' is a (ANSI SQL) timestamp literal.
It's equivalent to to_timestamp('2014-03-25 14:00:00', 'yyyy-mm-dd hh24:mi:ss') but I prefer the ANSI literal because it's less typing and works across multiple DBMS.
Here's an example of how to get 5 minutes ago in oracle. subtracting from a timestamp in increments of 1 where 1 is a day. so 5 minutes would be 5/(24hours*60min) of a day.
SELECT sysdate, sysdate-(5/(24*60)) as min_Ago5 from dual