Reputation: 13190
Using Postgres 9.3.5
My table has duration data in the as a text
field stored as minutes:seconds,
i.e 4:52
I want the value as total seconds (i.e 4 x 60) + 52 = 292
But table also contains values such as
3:34:21 (3 hours, 34 minutes and 21 seconds)
21 (21 seconds)
How can I write SQL to correct calculate duration in seconds for all these cases.
Update
select (case when duration like '%:%:%'
then extract(epoch from duration::time)
else extract(epoch from ('00:' || duration) ::time)
end
)as seconds
from discogs.track t1
;
So I have this but unfortunately some values are not quite valid causing it to fail
00:70:01
How do I either ignore such values or convert them (i.e 70 x 60 + 1)
Upvotes: 0
Views: 2203
Reputation: 1269463
You can convert the value to time and extract the time component. You do need to take the variable format into account:
select (case when t like '%:%:%'
then extract(epoch from t::time)
else extract(epoch from ('00:' || t) ::time)
end) as seconds
You added a new format. You can do:
select (case when t like '%:%:%'
then extract(epoch from t::time)
when t like '%:%'
then extract(epoch from ('00:' || t) ::time)
else t::int
end) as seconds
Upvotes: 0
Reputation: 23666
http://sqlfiddle.com/#!17/9eecb/19379
I expand %:%
text to %:%:%
texts and then simply split on delimiter ';'. So I am getting integer values which can be used in calculations.
SELECT
orig_duration,
hours_in_seconds + minutes_in_seconds + seconds as seconds
FROM (
SELECT
orig_duration,
(split_part(duration, ':', 1))::int * 60 * 60 as hours_in_seconds,
(split_part(duration, ':', 2))::int * 60 as minutes_in_seconds,
(split_part(duration, ':', 3))::int as seconds
FROM (
SELECT
duration as orig_duration,
case when duration like '%:%:%' then duration else '00:' || duration end as duration
FROM (
SELECT unnest(ARRAY['70:01','3:34:21','4:52']::text[]) as duration
)s
)s
)s
Result:
orig_duration seconds
------------- -------
70:01 4201
3:34:21 12861
4:52 292
Upvotes: 1