I am trying to find a way to have a SELECT statement return the set of dates between 2 input dates with a given interval. I would like to be able to easily change the time frame and interval that would be returned, so hard coding something with a series of SELECT ... UNIONs would not be ideal.
For example: I want all the dates at 5 second intervals for the last 60 seconds.
Expected:
times
---------------------
2009-02-05 08:00:00
2009-02-05 08:00:05
2009-02-05 08:00:10
2009-02-05 08:00:15
2009-02-05 08:00:20
...
2009-02-05 08:00:55
Edit:
generate_series(...) can be used in place of a table in the SELECT and simulates a table with a series of numbers in it with a given start value, end value and optionally a step. From there it can be CAST to the type I need for time functions and manipulated during the SELECT.
Thanks Quassnoi.
SELECT CAST (s || ' seconds' AS INTERVAL) + TIMESTAMP 'now'
FROM generate_series(0, -60, -5) s
Related
How to get datetime difference in postgres
I am using below syntax
DATE_PART('hour', A_column::timestamp-B_column::timestamp )
I want output like this:
If A_column=2020-05-20 00:00:00 and B_column=2020-05-15 00:00:00 I want to get 72(in hours).
Is there any possibility to skip weekends(Saturday and Sunday) in first one, it means to get the result as 72 hours(exclude weekend hours)
If A_column=2020-08-15 12:00:00 and B_column=2020-08-15 00:00:00 I want to get 12(in hours).
You could write this as:
select extract(epoch from a_column::timestamp - b_column::timestamp) / 60 / 60
from mytable
Rationale: substracting the two timestamps gives you an interval; you can then turn it to a number of seconds, and do arithmetics to convert that to hours.
I have a table in postgers with schema similar to this.
id start_time end_time
1 2019-10-21 20:00:00 UTC 2019-10-21 23:00:00 UTC
2 2019-10-21 22:00:00 UTC 2019-10-22 02:00:00 UTC
I want to write a query which will give me overlapping duration in database itself.
for example: given two inputs
t1=2019-10-21 21:00:00 UTC
t2=2019-10-22 01:00:00 UTC
the query should calculate all the overlapping time between the input range
the overlapping time between input and row 1 is 2 hrs
the overlapping time between input and row 2 is 3 hrs
the result wold be 2 + 3 = 5
Sounds as if you are looking for the intersection of two tsrange values:
tsrange(start_time, end_time, '[]') * tsrange('2019-10-21 21:00:00', '2019-10-22 01:00:00', '[]')
The '[]' specifies that both edges should be included in the range. This might or might not be what you want. You will need to adjust that to your requirements.
This will return a range type. To calculate the length of the range, subtract the upper value from the lower value:
select sum(upper(diff) - lower(diff))
from (
select tsrange(start_time, end_time, '[]') * tsrange('2019-10-21 21:00:00', '2019-10-22 01:00:00', '[]') as diff
from the_table
) t
This returns an interval representing the sum of all overlap.
If your column is a timestamp with time zone you need to use tstzrange instead.
Online example
You can use date arithmetics and aggregation:
select
sum(
greatest(
least(d.end_time, t.end_time) - greatest(d.start_time, t.start_time),
'0 hour'::interval
)
) total_overlap
from mytable t
cross join (values
('2019-10-21 21:00:00'::timestamp, '2019-10-22 01:00:00'::timestamp)
) d(start_time, end_time)
For each row, the difference between the smaller end time and the greatest start time gives you the duration of the overlap - if it is positive.
I am trying to calculate the time difference between two columns of a row which are of string data type. If the time difference between them is less than 2 hours then select the first column of that row else if the time difference is greater than 2 hours then select the second column of that row. It can be done by converting the columns to datetime format, but I want the result to be in string only. How can I do that? The data looks like this:
col1(string type)
2018-07-16 02:23:00
2018-07-26 12:26:00
2018-07-26 15:32:00
col2(string type)
2018-07-16 02:36:00
2018-07-26 14:29:00
2018-07-27 15:38:00
I think you don't need to convert the columns to datetime format, since the data in your case is already ordered (yyyy-MM-dd hh:mm:ss). You just need to take all the digits and take it into one string (yyyyMMddhhmmss) then you can apply your selection which is bigger or smaller than 2 hours (here 20000 since the hour is followed by mmss). By looking at your example (assuming col2 > col1), this query would work:
SELECT case when regexp_replace(col2,'[^0-9]', '')-regexp_replace(col1,'[^0-9]', '') < 20000 then col1 else col2 end as col3 from your_table;
Use unix_timestamp() to convert string timestamp to seconds.
The difference in hours will be:
hive> select (unix_timestamp('2018-07-16 02:23:00')- unix_timestamp('2018-07-16 02:36:00'))/60/60;
OK
-0.21666666666666667
Important update: this method will work correctly only if time zone is configured as UTC. Because for DST timezones for some marginal cases Hive converts time during timestamp operations. Consider this example for PDT time zone:
hive> select hour('2018-03-11 02:00:00');
OK
3
Note the hour is 3, not 2. This is because 2018-03-11 02:00:00 cannot exist in PDT time zone because exactly at 2018-03-11 02:00:00 time is adjusted and becomes 2018-03-11 03:00:00.
The same happens when converting to unix_timestamp. For PDT time zone unix_timestamp('2018-03-11 03:00:00') and unix_timestamp('2018-03-11 02:00:00') will return the same timestamp:
hive> select unix_timestamp('2018-03-11 03:00:00');
OK
1520762400
hive> select unix_timestamp('2018-03-11 02:00:00');
OK
1520762400
And few links for your reference:
https://community.hortonworks.com/questions/82511/change-default-timezone-for-hive.html
http://boristyukin.com/watch-out-for-timezones-with-sqoop-hive-impala-and-spark-2/
Also have a look at this jira please: Hive should carry out timestamp computations in UTC
how to get exact time Difference between two column
eg:
col1 date is 2014-09-21 02:00:00
col2 date is 2014-09-22 01:00:00
output like
result: 23:00:00
I am getting result like
Hours Minutes Seconds
--------------------
3 3 20
1 2 30
using the following query
SELECT start_time,
end_time,
DATE_PART(H,end_time) - DATE_PART(H,start_time) AS Hours,
DATE_PART(M,end_time) - DATE_PART(M,start_time) AS Minutes,
DATE_PART(S,end_time) - DATE_PART(S,start_time) AS Seconds
FROM user_session
but i need like
Difference
-----------
03:03:20
01:02:30
Use DATEDIFF to get the seconds between the two datetimes:
DATEDIFF(second,'2014-09-23 00:00:00.000','2014-09-23 01:23:45.000')
Then use DATEADD to add the seconds to '1900-01-01 00:00:00':
DATEADD(seconds,5025,'1900-01-01 00:00:00')
Then CAST the result to a TIME data type (note that this limits you to 24 hours max):
CAST('1900-01-01 01:23:45' as TIME)
Then LTRIM the date part of the value off the TIME data (as discovered by Benny). Redshift does not allow use of TIME on actual stored data:
LTRIM('1900-01-01 01:23:45','1900-01-01')
Now, do it in a single step:
SELECT LTRIM(DATEADD(seconds,DATEDIFF(second,'2014-09-23 00:00:00','2014-09-23 01:23:45.000'),'1900-01-01 00:00:00'),'1900-01-01');
:)
SELECT LTRIM(DATEADD(seconds,DATEDIFF(second,'2014-09-23 00:00:00','2014-09-23 01:23:45.000'),'1900-01-01 00:00:00'),'1900-01-01');
Here is my table. I need a query which returns the shift id for a specified time
How can I get the value?
shift_ID shift_From shift_To
1 2010-09-21 10:00:00.000 2010-09-21 18:10:00.000
2 2010-09-21 20:00:00.000 2010-09-21 05:00:00.000
Suppose I am giving 02:00:00 as input I need to get the shift ID as 1. How can I do this?
Try:
SELECT shift_ID
FROM time_shift
WHERE
DATEDIFF(hour, shift_From, shift_To) = 2 -- your input
See more about DATEDIFF on MSDN
The first argument is the time part you're specifying to DATETIFF (hour, minute, second).
If your input is strictly like 02:00:00 you need to parse it to determine what specify as the first argument.
To determine does the specified date belong between 2 others, use:
SELECT shift_ID
FROM time_shift
WHERE
CAST(shift_From AS TIME) < CAST(#input AS TIME)
AND
CAST(#input AS TIME) < CAST(shift_To AS TIME)
-- you can specify operators inclusiveness, i.e. <= >= etc
-- or
CAST(#input AS TIME) BETWEEN (CAST(shift_From AS TIME), CAST(shift_To AS TIME))
See more about TIME on MSDN