我遇到了一个特别的问题,我被困住了并寻求帮助...
我有一个时间序列类型的表,当设备打开或关闭时,我在其中存储开关切换值。状态0事件表示设备已关闭,状态1事件表示设备已打开。
time | state
------------------------------
2018-06-10 12:20:00 | 0
2018-06-10 12:30:00 | 1
2018-06-10 13:10:00 | 0
2018-06-10 16:50:00 | 1
2018-06-10 20:23:00 | 0
2018-06-10 21:10:00 | 1
2018-06-10 21:30:00 | 0
我需要按小时报告使用情况,这意味着生成如下输出:
date | in_use
-------------------------------
2018-06-10 12:00:00 | 1
2018-06-10 13:00:00 | 1
2018-06-10 14:00:00 | 0
2018-06-10 15:00:00 | 0
2018-06-10 16:00:00 | 1
2018-06-10 17:00:00 | 1
2018-06-10 18:00:00 | 1
2018-06-10 19:00:00 | 1
2018-06-10 20:00:00 | 1
2018-06-10 21:00:00 | 1
2018-06-10 22:00:00 | 0
我不确定如何使用postgres获得这种类型的结果。 你觉得呢?
谢谢!
答案 0 :(得分:3)
假设您要使用一个小时的状态,其中日志时间是小于该小时的最大时间(此后,您的示例在16:00错误(应为13:10)和21: 00(应为20:23的状态)):
使用generate_series()
获取所有时间。首先,在最短时间使用date_trunc()
,在结束时也使用date_trunc()
,但在最长时间上加上一个小时。
要获取最大时间少于一小时的状态,请使用相关子查询。因为在最初的一个小时内可能没有这种状态,所以子查询可能返回null。在这种情况下,请使用coalesce()
将否定值替换为日志中第一个值的取反(按时间排序)。
SELECT "gs"."date",
coalesce((SELECT "t2"."state"
FROM "elbat" "t2"
WHERE "t2"."time" < "gs"."date"
ORDER BY "t2"."time" DESC
LIMIT 1),
(SELECT NOT "t3"."state"
FROM "elbat" "t3"
ORDER BY "t3"."time" ASC
LIMIT 1)) "in_use"
FROM (SELECT generate_series(date_trunc('hour', min("t1"."time")),
date_trunc('hour', max("t1"."time"))
+ INTERVAL '1 HOUR',
'1 HOUR') "date"
FROM "elbat" "t1") "gs";