如何在 TimescaleDB 中一起查询最小值/最大值和日期使用 time_bucket

问题描述

我在时间刻度数据库(postgresql 13.3、TimescaleDB 2.2.1)中有一个包含两个相关列的“沙盒”表。

+------------------------------------+
| time  | timestamp without time zone|
+------------------------------------+
| value | double precision           |
+------------------------------------+

每秒都会在此表中输入一个值。我可以使用以下查询每隔 1 分钟从该表中获取最大值和最小值。

 SELECT 
    time_bucket('1 minutes',time) AS stamp,MIN(value) AS minValue,MAX(value) AS maxValue
 FROM sandBox
 GROUP BY stamp;

然而,这个查询只知道最小值和最大值,而不知道这些值对应的时间。我正在寻找与最小值/最大值相对应的查询。即类似:

+----------------------------------------------------------------------------------------+
| stamp               | min_time            | minValue | max_time            | maxnValue |
+----------------------------------------------------------------------------------------|
| 2021-06-14 00:00:00 | 2021-06-14 00:00:02 | 0        | 2021-06-14 00:00:44 | 22        |
| 2021-06-14 00:01:00 | 2021-06-14 00:01:59 | 2        | 2021-06-14 00:01:43 | 19        |
| 2021-06-14 00:02:00 | 2021-06-14 00:02:32 | 5        | 2021-06-14 00:02:24 | 26        |
| 2021-06-14 00:03:00 | 2021-06-14 00:03:52 | 1        | 2021-06-14 00:03:54 | 42        |
+----------------------------------------------------------------------------------------+

谢谢!

解决方法

因此,最简单的方法是使用 first/last 函数,但不是使用时间列进行排序,而是使用值列。所以首先按值= min 排序,最后按值= max 排序:

 SELECT 
    time_bucket('1 minutes',time) AS stamp,MIN(value) AS minValue
    first(time,value) AS minTime,MAX(value) AS maxValue,last(time,value) as maxTime
 FROM sandbox
 GROUP BY stamp;

这也可以像这样扩展到多列:

SELECT (mins).time as min_time,(mins).value as min_value ... (maxes).time as max_time ....
FROM (SELECT 
    time_bucket('1 minutes',first(s,value) AS mins,last(s,value) as maxes
 FROM sandbox s
 GROUP BY stamp) bookends;

您也可以使用诸如 (mins).* 之类的东西来获取所有列,但是它们会与原始列具有相同的名称并且它们会重复,因此您可能需要为每个列添加别名他们以这种方式单独。