downsample postgres中毫秒范围内的时间戳

v64noz0r  于 2021-08-09  发布在  Java
关注(0)|答案(1)|浏览(512)

我有一张table如下

  1. timestamp v1 v2 v3
  2. 2020/01/01 08:10:20.300 10 20 30
  3. 2020/01/01 08:10:20.306 11 21 31
  4. 2020/01/01 08:10:20.310 12 22 32
  5. 2020/01/01 08:10:20.318 13 23 33
  6. 2020/01/01 08:10:20.325 14 24 34
  7. .......................
  8. 2020/01/01 08:10:21.100 19 29 39

可以看出,时间戳在毫秒内变化不均匀,并且具有大量的细粒度数据。我有兴趣压缩表,使时间戳和数据列平均每100毫秒,即100毫秒之间的所有数据得到平均值。
我有一个解决方案,似乎是工作,但平均是超过每一秒,而不是每100毫秒后。

  1. SELECT date_trunc('second', timestamp) AS timestamp
  2. ,avg(v1) AS avg_v1
  3. ,avg(v2) AS avg_v2
  4. ,avg(v3) AS avg_v3
  5. FROM myTable
  6. GROUP BY 1;

请告诉我如何解决这个问题。谢谢您

zpqajqem

zpqajqem1#

考虑铸造 timestamp 列到 timestamp(1) :这实际上会将其四舍五入到最接近的小数点后一秒。

  1. SELECT
  2. "timestamp"::timestamp(1) AS timestamp,
  3. avg(v1) AS avg_v1,
  4. avg(v2) AS avg_v2,
  5. avg(v3) AS avg_v3
  6. FROM myTable
  7. GROUP BY 1;

请注意,这将舍入时间戳而不是截断它。一般来说, 08:10:20.306 会变成 08:10:20.3 ,而 08:10:20.350 会变成 08:10:20.4 . 这可能是,也可能不是你真正想要的。
如果你真的想把时间缩短到10秒,那就有点复杂了。一种方法是将时间戳截断为分钟,然后提取第二部分(包括所有小数),将其转换为数字,截断为1个小数,然后再将其加回去:

  1. SELECT
  2. date_trunc('minute', "timestamp")
  3. + interval '1 second'
  4. * trunc((extract(seconds from "timestamp"))::numeric, 1) AS timestamp,
  5. avg(v1) AS avg_v1,
  6. avg(v2) AS avg_v2,
  7. avg(v3) AS avg_v3
  8. FROM myTable
  9. GROUP BY 1;

另一个截短的选项,如gordonlinoff所评论的,是先偏移然后舍入。这比上述解决方案简单,而且可能更有效:

  1. SELECT
  2. ("timestamp" - interval '50 millisecond')::timestamp(1) AS timestamp,
  3. avg(v1) AS avg_v1,
  4. avg(v2) AS avg_v2,
  5. avg(v3) AS avg_v3
  6. FROM myTable
  7. GROUP BY 1;
展开查看全部

相关问题