【问题标题】:PosrgteSQL: the sum of the column values for the period depending on the step (day, month, year)PostgreSQL:根据步骤(日、月、年)的时间段的列值的总和
【发布时间】:2019-11-28 19:21:28
【问题描述】:

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

然后程序将数据返回给 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。

【问题讨论】:

    标签: laravel postgresql stored-procedures stored-functions


    【解决方案1】:

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

    更多信息在:set returning functions

    为了模拟你的情况,我创建了一个简单的表格:

    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()进行选择

    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
       ...
    

    【讨论】:

    • 谢谢。这几乎是我需要的。但不是当天的金额,而是当天的第一个值。还是谢谢
    • 您只需要当天的 first_value 吗?如果是,我编辑答案并展示如何使用窗口函数来解决这个问题。
    • 我需要每天的消费量(对不起我的英语)。可以说,我有table。因此,对于 2018-05-01,它将是每天所有记录的数量:5,52 + 4,32 + 2,16 + 2,4 + 2,41 ... 期间每一天都相同跨度>
    • 好的,我明白了。您正在使用时间戳。例如,在列period 上,我定义该列是DATE 类型。日期解决了这个问题。请注意,您的结果中有日期和时间。
    • 是的!谢谢!不幸的是,我没有足够的声誉将您的答案标记为有用。
    猜你喜欢
    • 1970-01-01
    • 2014-09-17
    • 2022-11-29
    • 1970-01-01
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    相关资源
    最近更新 更多