SQL Redshift difference in days between 2 timestamps - sql

In my Redshift table I have 2 columns that stores timestamp values: start_date_time and end_date_time.
I need to find the difference between start_date_time and end_date_time, such that, if difference is 1 day, then result should be 1. If diff is 12 hours, than result should be 0.5, if diff is 8 hours - than 0.3333 etc.
How can I do this? I tried to use datediff function: but that will not return what I wanted:
select datediff(day,'2011-12-31 8:30:00','2011-12-31 20:30:00') as day_diff;
Will result in 0. But I need 0.5, because difference is 12 hours.

Then just do it in hours and divide by 24.0?
DATEDIFF(HOUR,'2011-12-31 8:30:00','2011-12-31 20:30:00') / 24.0
Or for better granularity, in minutes or seconds?
DATEDIFF(MINUTE,'2011-12-31 8:30:00','2011-12-31 20:30:00') / 1440.0
DATEDIFF(SECOND,'2011-12-31 8:30:00','2011-12-31 20:30:00') / 86400.0

Use a smaller time unit:
select datediff(hour, '2011-12-31 8:30:00', '2011-12-31 20:30:00')/24.0 as day_diff;
Or:
select datediff(minute, '2011-12-31 8:30:00', '2011-12-31 20:30:00')/(24.0 * 60) as day_diff;
Or:
select datediff(second, '2011-12-31 8:30:00', '2011-12-31 20:30:00')/(24.0 * 60 * 60) as day_diff;

Related

How to extract the hour of day from an epoch and count each instance that occurs during that hour?

I have a question that I feel is pretty straight forward but is giving me some issues.
I have a column in table X called event_time which is an epoch. I am wanting to extract the hour of day out of that and count the number of rides that have occurred during that hour.
So the output will end up being a bar chart with x values 0-24 and the Y being the number of instances that occur (which is bike rides for example).
Here is what I have now, that isn't giving me the correct output:
select extract(hour from to_timestamp(start_time)::date) as hr,
count(*) as ct
from x
group by hr
order by hr asc
Any hints or help are appreciated.
Thanks
You can use arithmetic:
select floor( (start_time % (24 * 60 * 60)) / (60 * 60) ) as hour,
count(*)
from x
group by hour;
Or convert to a date/time and extract the hour:
select extract(hour from '1970-01-01'::date + start_time * interval '1 second') as hour, count(*)
from x
group by hour;

How to get epoch function in Oracle

select *
from sample_table scr
where extract('epoch' from systimestamp - scr.created_date)/60 > :defaultTimeOut
This is a postgres query. Trying to convert this query into oracle.
How do I convert epoch in oracle?
TIA.
You are actually trying to convert an interval (ie the difference between two dates) to a number of seconds. Assuming that created_date is of date datatype, one method is:
select *
from sample_table
where (sysdate - created_date) * 24 * 60 * 60 > :defaultTimeOut
Rationale: in Oracle, substracting two dates returns a decimal number that represents the difference in days. You can multiply that by 24 (hours per day), 60 (minutes per hour) and 60 (seconds per minute) to convert that to a number of seconds, then compare it to the target value.
If created_date is of timestamp datatype, you can cast it to a date first:
select *
from sample_table
where (sysdate - cast(created_date as date)) * 24 * 60 * 60 > :defaultTimeOut

duration between two columns with format hhmmss

How can I determine the difference / duration between two columns, which have the following format:
HHMMSS.
Leading zeros are swallowed by the system (Oracle DB).
0 o'clock is a "0".
3 o'clock is "300".
23:50 clock is "235000".
Whatever, 24:00 is also reported as "240000".
That means I have the column "Start" and the column "End".
How can you determine the duration using SQL?
Convert the values to seconds using arithmetic:
select hhmmss, floor(hhmmss / 10000) * 60 * 60 + (mod(hhmmss, 10000) / 100) * 60 + mod(hhmmss, 100)
from (select 235000 as hhmmss from dual) x
Then subtract the seconds. That will give you the duration in seconds.
With your column names, this would look like:
select ( (floor(end / 10000) * 60 * 60 + (mod(end, 10000) / 100) * 60 + mod(end, 100)) -
(floor(start / 10000) * 60 * 60 + (mod(start, 10000) / 100) * 60 + mod(start, 100))
) as diff_seconds
To convert this back to a string, you can use to_char():
select to_char(date '2000-01-01' + diff_seconds * interval '1' second, 'HH24:MI:SS')
You can achieve the duration in hour/minutes/seconds using to_date as following:
Select round(
(to_date(lpad(end,6,'0'),'HHMISS')
- to_date(lpad(start,6,'0'),'HHMISS') ) * 24
, 2) diff_in_hours
-- multiply it by another 60 to get diff in minutes (24*60)
-- multiply it by another 3600 to get diff in seconds (24*3600)
from your_table
To get the output in HHMISS just add it to sysdate
Select
TO_CHAR(Trunc(sysdate) + (to_date(lpad(end,6,'0'),'HHMISS')
- to_date(lpad(start,6,'0'),'HHMISS')) , 'HH:MI:SS') as diff_HHMISS
from your_table
Cheers!!

Converting query from Microsoft SQL to Oracle

The following Microsoft SQL query compares two date fields of a table and returns those records for which the difference in minutes is greater than 5.
SELECT t.Id, t.date1, t.date2,
DATEDIFF(MINUTE, t.date1 , t.date2) AS Mtime
FROM table1 t
WHERE
DATEDIFF(MINUTE,t.date1, t.date2) > 5
I have no idea how to write this with ORACLE. I've searched for solution and the closest I came to was :
SELECT t.date1, t.date2,
(t.date1 - t.date2) * 1440 AS Mtime
FROM table1 t
WHERE
(t.date1 -t.date2) * 1440 > 5
which gives me the error inconsistent datatypes: expected INTERVAL DAY TO SECOND got NUMBER
Does anyone know how to write this query with ORACLE ?
Don't use the difference. Just add the interval:
WHERE t.DeliveryDate >= t.Deadline + interval '5' minute
Or:
WHERE t.DeliveryDate >= t.Deadline + 5 / (24 * 60)
The equivalent in SQL Server is:
WHERE t.DeliveryDate >= DATEADD(minute, 5, t.Deadline)
This is a good habit. If one of the values is a constant, then the use of a function (- or datediff()) prevents the use of an index.
This should work -
SELECT t.Id, t.date1, t.date2,
(CAST(t.date1 AS DATE)-CAST(t.date2 AS DATE)) * 1440 AS Mtime FROM table1 t where (CAST(t.date1 AS DATE)-CAST(t.date2 AS DATE)) * 1440 > 5

LAG Function in Oracle

I have a table (incident) that has column Create_date(DataType=Date).
I want to get difference in Days OR Hours from Previous Record. Like the screenshot below.
From Second Record Create_Date I want to minus First Create_Date and from Third Create Date to Second and so on. I'm using LAG function in Oracle, but not sure how its calculating there. Could any one please help me regarding that issue.
incident.create_date - lag(incident.create_date,1) OVER (ORDER BY incident.create_date) AS CREATEDATE_DIFF,
RN 1 We have Create_date (05/01/017 10:40:17 AM
Date differences in Oracle are calculated in numbers of days. If the difference is less than a day, you're going to get a value of less than 1 returned.
If you want to convert that into hours, you'll have to multiply the result by 24, for minutes multiply by 24*60 and for seconds it's 24*60*60.
e.g.:
select sysdate - trunc(sysdate) diff_in_days,
(sysdate - trunc(sysdate))*24 diff_in_hours,
(sysdate - trunc(sysdate))*24*60 diff_in_mins,
(sysdate - trunc(sysdate))*24*60*60 diff_in_secs
from dual;
DIFF_IN_DAYS DIFF_IN_HOURS DIFF_IN_MINS DIFF_IN_SECS
------------ ------------- ------------ ------------
0.4342245370 10.4213888888 625.28333333 37517
You may then wish to apply ROUND (or maybe TRUNC/CEIL) depending on how you want the output to look like (e.g. to 2 d.p., to nearest minute, etc).
If you subtract one date from another you will get the difference in days (or fractions thereof) as a number.
You can get the days/hours/minutes/seconds of this using an interval:
SELECT EXTRACT( DAY FROM createdate_diff ) AS days,
EXTRACT( HOUR FROM createdate_diff ) AS hours,
EXTRACT( MINUTE FROM createdate_diff ) AS minutes,
EXTRACT( SECOND FROM createdate_diff ) AS seconds,
createdate_diff
FROM (
SELECT NUMTODSINTERVAL(
create_date - lag(create_date) OVER (ORDER BY create_date),
'DAY'
) AS CREATEDATE_DIFF
FROM incident
);
Or you can perform the same calculations manually:
SELECT TRUNC( createdate_diff ) AS days,
TRUNC( MOD( createdate_diff * 24, 24 ) ) AS hours,
TRUNC( MOD( createdate_diff * 24 * 60, 60 ) ) AS minutes,
MOD( createdate_diff * 24 * 60 * 60, 60 ) AS seconds,
createdate_diff
FROM (
SELECT create_date - lag(create_date) OVER (ORDER BY create_date)
AS CREATEDATE_DIFF
FROM incident
);
Use
......
(incident.create_date -
lag(incident.create_date,1) OVER (ORDER BY incident.create_date))
*24*60
AS CREATEDATE_DIFF_IN_MINS,.....
to get the output in minutes, which seams suitable for your sample data. Or multiply further by 60 to get output in seconds.