我有一张包含IoT设备数据的表,每小时发送一次测量值。必须获取今天,每周,每月和每年的报告。
使用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;
但是找不到多年来获取价值的好方法吗?有人尝试过吗?
时间表不支持年份,使用星期会导致错误的结果。
错误:不支持以月,年,世纪等形式定义的时间间隔
答案 0 :(得分:2)
请确保您知道实际上与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;
答案 1 :(得分:1)
暂时time_bucket
不支持月份/年份:请参见#414
time_bucket用于固定间隔,例如天,小时, 分钟。由于月份和年份是可变的时间单位,因此该函数 不支持他们
postgres date_trunc还支持月份/年份