获取间隔中每秒的数据

时间:2015-07-31 06:03:52

标签: postgresql

我想编写一个查询,它会在每秒的时间戳之间产生值,如果特定时间戳的值不存在,那么它应该为零。例如

  • 开始日期时间 - 27/7/2015 10:00:00
  • 结束日期时间 - 27/7/2015 10:05:00

然后结果应该是

27/7/2015 10:00:00                10 [start date time]
27/7/2015 10:00:01                19
27/7/2015 10:00:02                23
27/7/2015 10:00:03                0 [Value not present in table for this timestamp]
27/7/2015 10:00:04                45
27/7/2015 10:00:05                0 [Value not present in table for this timestamp]
...
27/7/2015 10:05:00                42 [end date time ]

我正在尝试此查询但未获得所需的结果

SELECT CAST(date_trunc('second', CAST(to_timestamp(t1.timestamp_col,'DD-MM-YYYY HH24:MI:SS')as timestamp without time zone) + interval '1 second') as text) 
     , NULLIF(t1.y_temperature_col,'00')
FROM   historical_trend_data t1
WHERE  CAST(to_timestamp(t1.timestamp_col,'DD-MM-YYYY HH24:MI:SS') as timestamp without time zone) BETWEEN CAST(to_timestamp('28/7/2015 10:00:00','DD-MM-YYYY HH24:MI:SS')as timestamp without time zone) AND  CAST(to_timestamp('28/7/2015 18:00:00','DD-MM-YYYY HH24:MI:SS') as timestamp without time zone);

这是功能

CREATE OR REPLACE FUNCTION timestampwise_sp2(IN startdatetime text, IN enddatetime text,
                                             OUT x_time_col text, OUT temperature text)
RETURNS SETOF record AS $BODY$
BEGIN
  return query
    with simul_data as(
      SELECT generate_series(startdatetime::timestamp,
                             enddatetime::timestamp, '1 Seconds') As x_time_col
    ) 
    Select simul_data.x_time_col::text, coalesce(t1.y_temperature_col, '0') AS temperature
    from historical_trend_data t1
    LEFT JOIN simul_data ON CAST(to_timestamp(t1.timestamp_col,'DD-MM-YYYY HH24:MI:SS') as timestamp without time zone) = simul_data.x_time_col;
END; $BODY$ LANGUAGE plpgsql VOLATILE;

但它没有产生预期的结果

1 个答案:

答案 0 :(得分:0)

SELECT s.sec AS obs_time, coalesce(t1.y_temperature_col, 0) AS temperature
FROM generate_series('28-07-2015 10:00:00'::timestamp,
                     '28-07-2015 18:00:00'::timestamp, '1 minute') AS s(sec)
LEFT JOIN t1 ON timestamp_col = s.sec;

generate_series()函数返回序列中的一组记录,在这种情况下,从起始点到结束点的第二个间隔。这与您的实际数据保持联系,温度的任何NULL值都会使用coalesce()函数转换为0。

在功能形式中它会是这样的:

CREATE FUNCTION timestampwise_sp2(startdatetime timestamp, enddatetime timestamp) AS $$
  SELECT to_char(simul_data.x_time_col, 'DD/MM/YYYY HH24:MI:SS') AS x_time_col,
         coalesce(t1.y_temperature_col, '0') AS temperature
  FROM generate_series($1, $2, '1 second') AS simul_data(x_time_col)
  LEFT JOIN historical_trend_data t1
    ON to_timestamp(t1.timestamp_col,'DD/MM/YYYY HH24:MI:SS') = simul_data.x_time_col;
$$ LANGUAGE sql STRICT;

请注意,这是sql语言函数,比plpgsql快。