Trying to get HH:MM:SS from milliseconds in Presto - sql

I'm trying to convert milliseconds to format HH:MM:SS or MM:SS, but I keep getting the same error.
Here's the error:
java.sql.SQLException: [Simba][AthenaJDBC](100071) An error has been thrown from the AWS Athena client. SYNTAX_ERROR: line 5:19: Unexpected parameters (time, varchar(5)) for function date_format. Expected: date_format(timestamp with time zone, varchar(x)) , date_format(timestamp, varchar(x)) [Execution ID: 89bfd858-9992-439f-ad84-b59bfd1cbde8]
Here's my code:
SELECT
column_a,
round(AVG((milliseconds) / 1000)) AS Seconds,
(case when milliseconds/1000 < 60 * 60
then time '00:00:00' + milliseconds * interval '1' second, '%i:%s'
else time '00:00:00' + milliseconds * interval '1' second, '%H:%i:%s'
end) as hhmmss,
round((AVG((column_b)) / 1099511627776),2) AS b,
COUNT(column_c) AS c
FROM
table
GROUP BY
column_a
Tried with this one as well
(case when milliseconds/1000 < 60 * 60
then date_format(time '00:00:00' + milliseconds * interval '1' second, '%i:%s')
else date_format(time '00:00:00' + milliseconds * interval '1' second, '%H:%i:%s')
end) as hhmmss
Any help, please?

You can just cast your time to timestamp:
select date_format(cast(time '00:00:00' + 23 * interval '1' second as timestamp), '%H:%i:%s')
Output:
_col0
00:00:23
Note that this will work only if you have less than 24 hours interval in your milliseconds, otherwise you will need to do math yourself and concat results into desired string.
P.S. Should not milliseconds * interval '1' second be (milliseconds/1000) * interval '1' second?

Related

Convert Timestamp to minutes in Oracle after a subtraction

I'm trying to get the minute value from a Timestamp after a subtraction
First I made a subtraction:
Current Time - Target Time(INSP_FIN_DT)
(
TO_TIMESTAMP(TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS'),'YYYY-MM-DD HH24:MI:SS') -
TO_TIMESTAMP(INSP_FIN_DT,'YYYY-MM-DD HH24:MI:SS')
) AS REST_TIME
the output:
+00 00:09:44.000000
What I need:
09
I already tried
SELECT SUBSTR(REST_TIME, 7,2)
But the return is ever 00, even If I convert it to Char like:
SELECT SUBSTR(TO_CHAR(REST_TIME),7,2)
How can I solve it by query?
Information here https://dba.stackexchange.com/questions/53924/how-do-i-get-the-difference-in-minutes-from-2-timestamp-columns
select
round(
(SYSDATE - cast(<other_timestamp> as date))
* 24 * 60
) as diff_minutes
from <some_table>;
For my current implementation, I'll never have more than a hour, in this case I used the bellow solution:
SYSTIMESTAMP - TO_TIMESTAMP(INSP_FIN_DT,'YYYY-MM-DD HH24:MI:SS') AS REST_TIME
Select..
EXTRACT(MINUTE FROM REST_TIME) AS REST_MINUTES
In case of more than 60 minutes, I should use:
(EXTRACT(HOUR FROM REST_TIME) * 60)
+ EXTRACT(MINUTE FROM REST_TIME) AS REST_MINUTES

Getting a count of timestamps that fall into each 5 minute bucket

I have a table of timestamps. I'd like to group them into 5 minute buckets and get the count of timestamps in that bucket. I having some trouble getting the SQL quite right. I am using Postgres. It's telling me the timestamp column in the last line doesn't exist, but it's defined as an alias.
SELECT
TIMESTAMP WITH TIME ZONE 'epoch' +
INTERVAL '1 second' * round(extract('epoch' from my_timestamp) / 300) * 300
as timestamp,
count(my_timestamp)
FROM logs
GROUP BY
round(extract('epoch' from timestamp) / 300)
I think your GROUP BY is off. Try this:
SELECT TIMESTAMP WITH TIME ZONE 'epoch' + INTERVAL '1 second' * round(extract('epoch' from my_timestamp) / 300) * 300 as timestamp,
count(*)
FROM (values (now())) logs(my_timestamp)
GROUP BY timestamp

Redshift - Converting UTC data to other timezones

I am trying to convert data from UTC to various European timezones. I am using a case statement and find only the first condition in the case statement is executed while the other conditions are not checked.
SELECT sale_id,appointment_time,timezone,
case when timezone = 'EDT' then (appointment_time + interval '-4' HOUR * 1)
when timezone = 'BST' then (appointment_time + interval '1' HOUR * 1)
when timezone = 'CEST' then (appointment_time + interval '2' HOUR * 1)
when timezone = 'EEST' then (appointment_time + interval '3' HOUR * 1)
when timezone = 'MSK' then (appointment_time + interval '3' HOUR * 1)
when timezone = 'WEST' then (appointment_time + interval '1' HOUR * 1)
else null
end as NewTime
FROM sales
Could anyone advice as to where am I going wrong. Thanks
you missed else just add before end and use dateadd function
SELECT sale_id,appointment_time,timezone,
case when timezone = 'EDT' then dateadd(h,-4,appointment_time)
when timezone = 'BST' then dateadd(h,1,appointment_time)
--------------
--------------
else null
end as NewTime
FROM sales
Why don't you use built in convert_timezone function. It would be faster since you don't need to use a case
SELECT sale_id, appointment_time, timezone,
convert_timezone(timezone, appointment_time) as NewTime
FROM sales

SQL extract hour from timestamp

This query: select EXTRACT(HOUR FROM 1435047532) as hour from TABLENAME;
Returns this error: "invalid extract field for extract source".
I'm trying to extract the hour from a given timestamp. Maybe the problem is the format of timestamp field is NUMBER and not TIMESTAMP?
You can convert your numeric seconds-since-epoch time to a TIMESTAMP type using:
TIMESTAMP '1970-01-01 00:00:00' + NUMTODSINTERVAL( your_time_since_epoch, 'SECOND' )
So to get the hours:
SELECT EXTRACT( HOUR FROM TIMESTAMP '1970-01-01 00:00:00'
+ NUMTODSINTERVAL( 1435047532, 'SECOND' ) )
FROM DUAL;
If you need to handle leap seconds then you will need to create a function/package to handle this.
try this
select extract(hour from (select to_date('19700101', 'YYYYMMDD')
+ ( 1 / 24 / 60 / 60 ) * 1435047532 from dual)) from dual

Calculate Average Time Over 24 hour period

I'm working in Teradata and am trying to calulate the average time a job completes.
Data Values:
Job Name Start Date End Date End Time
D_BDW_CCIP_SRM_LD 10/10/2012 10/11/2012 01:41:49
D_BDW_CCIP_SRM_LD 10/9/2012 10/10/2012 00:19:56
D_BDW_CCIP_SRM_LD 10/8/2012 10/8/2012 23:37:18
D_BDW_CCIP_SRM_LD 10/5/2012 10/5/2012 23:39:47
D_BDW_CCIP_SRM_LD 10/4/2012 10/4/2012 23:42:47
D_BDW_CCIP_SRM_LD 10/3/2012 10/3/2012 23:41:54
The average is coming back with 16:07 instead of 00:07. What I need to happen is that the calculations where the job finishes next day understands that the time expanded.
In Excel I could do this by adding one day to the end time and then averaging and displaying as a time.
How do I do this in Teradata?
This is such an interesting question! UPDATED with correct syntax: Assuming your START_DATE and END_DATE are DATE values and END_TIME is a TIME value, here is a solution:
select cast( avg( case
when start_date <> end_date
then extract(second from end_time)
+ extract(minute from end_time) * 60
+ extract(hour from end_time) * 3600
+ 86400
else extract(second from end_time)
+ extract(minute from end_time) * 60
+ extract(hour from end_time) * 3600
end) mod 86400) as decimal(10,4))
* INTERVAL '00:00:01.00' HOUR TO SECOND as avg_time
from your_table
The CASE expression "adds" one day (86,400 seconds) as you suggested when using Excel to determine the average seconds since midnight into an intermediate result and converted into a TIME column.
To be fair, I received help from the Teradata Forum formatting the result, but I like this so much I'll be using it myself.
This seems to do the trick, but I'd be interested in seeing if there is another way.
SELECT job_name,
case when avg_end_time_in_minutes > 60*24 then avg_end_time_in_minutes - 60*24
else avg_end_time_in_minutes end as avg_adjusted,
case when max_end_time_in_minutes > 60*24 then max_end_time_in_minutes - 60*24
else max_end_time_in_minutes end as max_adjusted,
CAST((CAST(avg_adjusted / 60 AS INTEGER) (FORMAT '9(2)')) AS CHAR(2))||':'||
CAST((CAST((avg_adjusted / 60 MOD 1)*60 AS INTEGER) (FORMAT '9(2)')) AS CHAR(2))
avg_adjusted_time,
CAST((CAST(max_adjusted / 60 AS INTEGER) (FORMAT '9(2)')) AS CHAR(2))||':'||
CAST((CAST((max_adjusted / 60 MOD 1)*60 AS INTEGER) (FORMAT '9(2)')) AS CHAR(2))
max_adjusted_time
FROM (
SELECT job_name,
AVG(end_time_in_minutes) avg_end_time_in_minutes,
MAX(CAST(end_time_in_minutes AS DECIMAL(8,2))) max_end_time_in_minutes
FROM (
SELECT job_name,
CAST(substr(end_time, 1, 2) AS INTEGER)*60
+ CAST(substr(end_time, 4, 2) AS INTEGER)
+ cast(end_date - start_date as integer)*60*24 AS end_time_in_minutes
FROM dabank_prod_ops_tb.bdw_tables_load_tracker_view a
WHERE a.status = 'COMPLETED'
AND a.start_date BETWEEN CURRENT_DATE - 31 AND CURRENT_DATE -1
AND a.end_time IS NOT NULL
) a
GROUP BY 1
) b
First, figure out the number of seconds that the end time is from midnight on the start date. We can then use that to calculate the average number of seconds taken, and then add that to midnight to find the average end time.
select
avg(extract(second from end_time) + 60 *
(extract(minute from end_time) + 60 *
(extract(hour from end_time) + 24 *
(end_date - start_date))) as avg_duration_in_seconds
cast(avg_duration_in_seconds / 60 / 60 as integer) as avg_hours
mod(cast(avg_duration_in_seconds / 60 as integer), 60) as avg_minutes
mod(cast(avg_duration_in_seconds as integer), 60) as avg_seconds,
cast('00:00:00' as time) +
cast(avg_hours as interval hour) +
cast(avg_minutes as interval minute) +
cast(avg_seconds as interval second) as avg_end_time
from my_table
Be aware though that if the average ends up over 24 hours, avg_end_time will be something like 00:01:15 rather than 24:01:15.