PostgreSQL рассчитывает средние значения для частей дня - PullRequest
0 голосов
/ 23 мая 2018

У меня есть таблица postgres с измеренными температурами и отметкой времени измерения.Интервал измерения составляет 30 минут, но иногда он пропускается, поэтому я не получаю одинаковое количество измерений каждый день.

Таблица выглядит следующим образом:

enter image description here

Мне нужно создать представление, которое показывает среднюю температуру для каждого дня, разделенную на четыре 6часовые интервалы: 00-06, 06-12, 12-18 и 18-24.Это должно выглядеть примерно так:

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 |

и т. Д.и т.д.

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Если вам также нужны средние значения для интервалов без каких-либо измерений, вам понадобится календарь-таблица :


-- \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
        ;
0 голосов
/ 23 мая 2018

Вы можете округлить временные метки до четвертей дня со следующим выражением (на примерных данных):

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)    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...