Reputation: 771
I have a postgres table with measured temperatures and timestamp of measurement. Measuring interval is 30 minutes, but sometimes it skips, so I don't get the same number of measurements each day.
The table looks like this:
I need to create a view that shows average temperature for each day divided into four 6 hour intervals: 00-06, 06-12, 12-18 and 18-24. It should look something like this:
avg_temp, time
|24.5 | 2018-05-13 00:00:00 |
|22.1 | 2018-05-13 06:00:00 |
|25.6 | 2018-05-13 12:00:00 |
|20.6 | 2018-05-13 18:00:00 |
|21.8 | 2018-05-14 00:00:00 |
etc. etc.
Upvotes: 3
Views: 3134
Reputation: 44250
If you also need the averages for intervals without any measurements, you'll need a calendar-table:
-- \i tmp.sql
CREATE TABLE the_temp(
ztime timestamp primary key
, ztemp double precision
) ;
INSERT INTO the_temp( ztemp, ztime )
VALUES (20, '2018-05-20 4:00')
, (21, '2018-05-20 5:00')
, (22, '2018-05-20 6:00')
, (23, '2018-05-20 7:00')
, (24, '2018-05-20 12:00')
, (25, '2018-05-20 19:00')
;
-- Generate calendar table
WITH cal AS(
SELECT ts AS t_begin, ts+ '6hours'::interval AS t_end
FROM generate_series('2018-05-20 0:00'::timestamp
, '2018-05-21 0:00', '6hours'::interval) ts
)
SELECT cal.t_begin, cal.t_end
, AVG( tt.ztemp)AS zmean
FROM cal
LEFT JOIN the_temp tt
ON tt.ztime >= cal.t_begin
AND tt.ztime < cal.t_end
GROUP BY cal.t_begin, cal.t_end
;
Upvotes: 2
Reputation: 121889
You can round timestamps to quarters of a day with the following expression (on an exemplary data):
with my_table(temp, time) as (
values
(20, '2018-05-20 4:00'::timestamp),
(21, '2018-05-20 5:00'),
(22, '2018-05-20 6:00'),
(23, '2018-05-20 7:00'),
(24, '2018-05-20 12:00'),
(25, '2018-05-20 19:00')
)
select avg(temp), time::date + (extract(hour from time)::int/ 6* 6)* '1h'::interval as time
from my_table
group by 2
order by 2
avg | time
---------------------+---------------------
20.5000000000000000 | 2018-05-20 00:00:00
22.5000000000000000 | 2018-05-20 06:00:00
24.0000000000000000 | 2018-05-20 12:00:00
25.0000000000000000 | 2018-05-20 18:00:00
(4 rows)
Upvotes: 5