PostgreSQL:根据步骤(日、月、年)计算期间的列值总和

PosrgteSQL: the sum of the column values for the period depending on the step (day, month, year)

我想创建一个存储过程或函数,returns 根据步骤(日、月、年)计算期间列值的总和。例如,我有 table 消费数据。它每 15 分钟保存一次数据。我想获得 2019-05-01 至 2019-05-10 期间的报告,步骤为“1 天”。我需要为这个时间间隔内的每一天定义一个每日数据集,并获取每一天的值的总和。

然后程序returns数据到Laravel。基于此数据图表构建。

我现在的代码:

CREATE OR REPLACE FUNCTION "public"."test"("meterid" int4, "started" text, "ended" text, "preiod" text)
  RETURNS TABLE("_kwh" numeric, "datetime" timestamp) AS $BODY$BEGIN

    RETURN QUERY

    SELECT kwh, a_datetime 
    FROM "public"."consumption" 
    WHERE meter_id = meterid 
    AND a_datetime 
        BETWEEN to_timestamp(started, 'YYYY-MM-DD HH24:MI:SS') 
        AND to_timestamp(ended, 'YYYY-MM-DD HH24:MI:SS');

END$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100
  ROWS 1000

我正在使用 PostgreSQL 10.7。

您可以使用pg_generate_series(start, end, interval)

更多信息见:set returning functions

为了模拟您的情况,我创建了一个简单的 table:

postgres=# create table consumption (kwh int, datetime date);
CREATE TABLE
postgres=# insert into consumption values (10, 2019-01-01);
ERROR:  column "datetime" is of type date but expression is of type integer
postgres=# insert into consumption values (10, '2019-01-01');
INSERT 0 1
postgres=# insert into consumption values (2, '2019-01-03');
INSERT 0 1
postgres=# insert into consumption values (24, '2019-03-06');
INSERT 0 1
postgres=# insert into consumption values (30, '2019-03-22');
INSERT 0 1

并用 generate_series()

制作了 select
postgres=# SELECT COALESCE(SUM(kwh), 0) AS kwh, 
                  period::DATE     
             FROM GENERATE_SERIES('2019-01-01','2019-12-31', '1 day'::interval) AS period
        LEFT JOIN consumption ON period::DATE=datetime::DATE 
         GROUP BY 2

 kwh |   period   
-----+------------
   0 | 2019-04-17
   0 | 2019-05-29
   ....
   0 | 2019-04-06
   0 | 2019-04-26
   2 | 2019-01-03
   0 | 2019-03-15
   ...
   0 | 2019-11-21
   0 | 2019-07-24
  30 | 2019-03-22
   0 | 2019-05-22
   0 | 2019-11-19
   ...