Domanda

I have the below data.

0:00:00
0:30:00
1:00:00
1:30:00
2:00:00
2:30:00
3:00:00
3:30:00
4:00:00
4:30:00
5:00:00
5:30:00
6:00:00
6:30:00

I can extract the hour the using EXTRACT(HOUR FROM TIMESTAMP) but this will give me 24 hours.

But now I need to some different calculation where I can get numbers from 1-48 based on the time given.

Something like this:

0:00:00 1
0:30:00 2
1:00:00 3
1:30:00 4
2:00:00 5
2:30:00 6
3:00:00 7
3:30:00 8
4:00:00 9
4:30:00 10
6:00:00 13
6:30:00 14

Note the skipped 11 and 12, for the absent values 5:00 and 5:30.

Is there any possibilities that I can get that result in PostgreSQL?

È stato utile?

Soluzione

Simply use formula 1 + extract(hour from 2 * tm) - it gives your expected result exactly - obligatory SQLFiddle.

Altri suggerimenti

This will give you a double precision result, that you can round to whatever you want:

2 * (EXTRACT(HOUR FROM t) + EXTRACT(MINUTE FROM t) / 60) + 1

EDIT:

Or, as @CraigRinger suggested:

EXTRACT(EPOCH FROM t) / 1800 + 1

For the later, t needs to be TIME, not TIMESTAMP. Use cast if needed.
UPDATE: This will work with INTERVALs too.

SELECT 2 * (EXTRACT(HOUR FROM t) + EXTRACT(MINUTE FROM t) / 60) + 1,
       EXTRACT(EPOCH FROM t) / 1800 + 1
FROM (VALUES (time '4:30:00'), (time '7:24:31'), (time '8:15:00')) as foo(t)

-- results:

?column? | ?column?
---------+---------
10       | 10
15.8     | 15.8172222222222
17.5     | 17.5

But as you wrote, there will be no edge cases (when the time cannot be divided with 30 minutes).

select 
case 
when date_time_field_of_interest::time >= '00:00:00' and date_time_field_of_interest::time < '00:30:00' then 1 
when date_time_field_of_interest::time >= '00:30:00' and date_time_field_of_interest::time < '01:00:00' then 2  
....
end 
from your_table; 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top