简体   繁体   中英

Redshift: Conversion of string field in HH:MM:SS format to seconds and backwards

  1. I've been searching for an easy way to convert a string field from HH:MM:SS format to seconds in Redshift, since the TIME_TO_SEC function doesn't exist.

    I have a call center database with a string field in this format, HH:MM:SS . For example, if it was 00:05:10 then I would need to convert it to 310 . I came up with the following on my own but there's got to be a better way:

     (SPLIT_PART("HANDLE TIME", ':', 1) * 3600) + (SPLIT_PART(SPLIT_PART("HANDLE TIME", ':', 2),':', 1) * 60) + CAST(SPLIT_PART("HANDLE TIME", ':', 3) AS INT)
  2. Once I sum up the seconds I need to convert the seconds back to the HH:MM:SS format. So 1249 would become the string 00:20:49 . So simple in MYSQL, not so much in RedShift.

Any help would be greatly appreciated.

Unfortunately, I don't have Redshift on hand, but you can do something like:

select datediff(second,
                timestamp('2000-01-01'),
                timestamp('2000-01-01 ' || handle_time)
               )

Redshift doesn't have functions specifically for this. But, it has a great feature, called UDF , which supports python, hence it will be the perfect fit.

1.To convert seconds to hh:mm:ss (or days, hh:mm:ss), create this UDF in redshift -

CREATE FUNCTION to_hhmmss (a bigint)
RETURNS character varying
STABLE
AS $$
  import datetime
  return str(datetime.timedelta(seconds=a))
$$ LANGUAGE plpythonu;

It accepts an 'big integer' (seconds) value as a parameter and returns a string (time in hh:mm:ss format)

Example Output -

db=# select to_hhmmss_1(12004);
 to_hhmmss_1
-------------
 3:20:04
(1 row)

db=# select to_hhmmss_1(120040);
  to_hhmmss_1
----------------
 1 day, 9:20:40
(1 row)

2.To convert hh:mm:ss to seconds -

CREATE FUNCTION to_seconds (time_str varchar(20))
RETURNS integer
STABLE
AS $$
  h, m, s = time_str.split(':')
  return int(h) * 3600 + int(m) * 60 + int(s)
$$ LANGUAGE plpythonu;

This function will accept a string (time in hh:mm:ss) and return an integer (seconds). Example Output -

db=# select to_seconds('1:00:00');
 to_seconds
------------
       3600
(1 row)

You can use cast and trim (but you can also use extract)

Using cast and trim:

select
'10:20:23' as time_col,
cast(trim(split_part(time_col, ':', 1)) as int) * 3600 + cast(trim(split_part(time_col, ':', 2)) as int) * 60 + cast(trim(split_part(time_col, ':', 3)) as int) as total_seconds

time_col | total_seconds
10:20:23 | 37223

if you have mm:ss instead you can just "shift" everything down

select
'20:23' as time_col,
cast(trim(split_part(time_col, ':', 1)) as int) * 60 + cast(trim(split_part(time_col, ':', 2)) as int) as total_seconds

time_col | total_seconds
20:23    | 1223

Using Extract:

select
'10:20:23' as time_col,
extract(hour from time_col::time) as hour,
extract(minute from time_col::time) as minute,
extract(second from time_col::time) as second,
hour * 3600 + minute * 60 + second as total_seconds 

time_col|hour|minute|second|total_seconds
10:20:23|10  |20    |23    |37223

Extract doesn't work well with MM:SS since you have to cast as time.

Going back to a timestamp/time format:

to_char(date_trunc('second', interval '1 second' * total_seconds), 'HH24:MI:SS') as time_format

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM