条件时间序列数据聚合

时间:2016-03-01 16:31:13

标签: postgresql time-series aggregate-functions

我有一个关系数据库(postgres),其中包含一个包含时间序列指标的表。每行由 - obj_id, metric_id, timestamp, value

组成

假设我有3个感兴趣的指标代码 - 1,4,5。我想过滤掉所有对象,对于相同的时间戳(让我们假设所有度量的时间戳都是固定的时间间隔),具有度量1< 10和(度量4 +度量5)< 10具有此事件发生的具体时间戳。

更具体的例子:

obj_id       metric_id         timestamp        value
------------------------------------------------------
1             1                83827             9
1             4                83827             2
1             5                83827             1
2             1                73261             11
2             4                73261             2
2             5                73261             5
1             1                92381             24
1             4                92381             10
1             5                92381             100
2             1                38239             7
2             4                38239             3
2             5                38239             4

预期结果将是:

obj_id     timestamp
---------------------
  1         83827
  2         38239

我试图创建一个有效的查询。这就是我想到的,为了获得相同时间戳的4 + 5的总和,但我不确定将这些查询粘合在一起的最佳方法是什么:

SELECT obj_id, timestamp, sum(value) AS x
FROM metric
WHERE metric_id = 4 OR metric_id = 5
group by obj_id, timestamp

我不确定如何添加到此查询指标1(我们应该单独查询),然后按obj_idtimestamp过滤掉结果。

我想过可能会使用自联接,通过时间戳加入同一个表的两个内部选择。

2 个答案:

答案 0 :(得分:3)

SQL Fiddle

booleaninteger的演员阵容产生0或1

select obj_id, timestamp
from metric
where metric_id in (1,4,5)
group by obj_id, timestamp
having
    sum(value * (metric_id in (4,5))::integer) < 10
    and
    sum(value * (metric_id = 1)::integer) < 10

答案 1 :(得分:0)

可能这可以做得更好,但这感觉很难理解(需要9.4 + ):

WITH x AS(
  SELECT 
    obj_id,
    timestamp,
    min(value) FILTER (WHERE metric_id = 1) as metric1,
    min(value) FILTER (WHERE metric_id = 4) as metric4,
    min(value) FILTER (WHERE metric_id = 5) as metric5
  FROM metric
  GROUP BY obj_id, timestamp
)
  SELECT obj_id, timestamp
  FROM x
  WHERE metric1 < 10
    AND (metric4 + metric5) < 10
相关问题