2

我有一张包含物联网设备数据的表格,每小时发送一次测量值。必须获得今天、周、月和年的报告。

使用 timescaleDB,我得到了今天、周和月的一些“好的”结果。例如每月:

   SELECT
      time_bucket('4 weeks', measured_at) AS month,
      MAX(CAST(data->>'1_8_0' AS DOUBLE PRECISION)) - MIN(CAST(data->>'1_8_0' AS DOUBLE PRECISION)) as consumption
      FROM readings
      WHERE device_id = 4
      GROUP BY month
      ORDER BY month DESC LIMIT 12;

但是多年找不到取值的好方法?有人试过吗?

时间刻度不支持年份,使用周会导致错误结果。

错误:不支持按月、年、世纪等定义的间隔

4

2 回答 2

3

目前time_bucket不支持月/年:见#414

time_bucket 设计用于定期间隔,如天、小时、分钟。由于月和年是可变时间单位,因此该函数不支持它们

postgres date_trunc也支持月/年

于 2019-04-22T10:07:34.083 回答
3

请确保您知道您实际汇总了哪些数据time_bucket

TIMESTAMPTZ 参数按 UTC 时间存储。所以桶的对齐是在UTC时间。这样做的一个结果是,每日存储桶与午夜 UTC 对齐,而不是本地时间。

正如@TmTron 已经指出的那样,几个月和几年的实际正确版本将date_trunc如下使用:

SELECT
    date_trunc('month', measured_at) AS month,
    MAX(CAST(data->>'1_8_0' AS DOUBLE PRECISION)) - MIN(CAST(data->>'1_8_0' AS DOUBLE PRECISION)) as consumption
    FROM readings
    WHERE device_id = 4
    GROUP BY 1
    ORDER BY 1 DESC LIMIT 12;

...和:

SELECT
    date_trunc('year', measured_at) AS year,
    MAX(CAST(data->>'1_8_0' AS DOUBLE PRECISION)) - MIN(CAST(data->>'1_8_0' AS DOUBLE PRECISION)) as consumption
    FROM readings
    WHERE device_id = 4
    GROUP BY 1
    ORDER BY 1 DESC LIMIT ...;

如果您只选择某个时间间隔(例如过去 12 个月),请始终添加一个条件来减少要扫描的分区数量,例如:

SELECT
    date_trunc('month', measured_at) AS month,
    MAX(CAST(data->>'1_8_0' AS DOUBLE PRECISION)) - MIN(CAST(data->>'1_8_0' AS DOUBLE PRECISION)) as consumption
    FROM readings
    WHERE device_id = 4
        AND measured_at >= CURRENT_TIMESTAMP - '13 months'::interval
    GROUP BY 1
    ORDER BY 1 DESC LIMIT 12;
于 2019-04-22T17:01:10.373 回答