计算 TimescaleDB 中值相对于上次读数的变化

2024-02-05

我在 TimescaleDB 中存储了有关一组电池的时间序列数据,这些数据记录了每个电池每次的“充电状态”。我没有测量流入和流出的流量,只有瞬时充电状态。

从这些数据中,我想找到每次充电状态的变化,稍后我将把它存储在几个小时内的消耗中(在做了一些特定于电池的数学计算之后)。

我写了一个 SQL 查询来实现我的目标:

SELECT time, charge - LAG(charge) OVER (ORDER BY time) AS delta_soc FROM charge_data;

把它放在一个Postgres 生成的列 https://www.postgresql.org/docs/12/ddl-generated-columns.html:

ADD COLUMN delta_soc smallint GENERATED ALWAYS AS (charge - LAG(charge) OVER (ORDER BY time)) STORED

正如文档中所承诺的那样,失败了,因为它引用了另一行。

所以,我(成功)做出了一个物化视图:

CREATE MATERIALIZED VIEW delta_soc AS
SELECT
  time,
  batt_uid,
  charge,
  (charge-LAG(charge) OVER (ORDER BY time)) as delta_charge,
  EXTRACT(EPOCH FROM time-LAG(time) OVER (ORDER BY time)) as delta_time
FROM charge_data 
ORDER BY time;

但如果能近乎实时地获得这些数据那就太好了。毕竟,仅提供上次值的更改是一个“简单”的操作。所以,我查看了 Timescale 的连续聚集体 https://docs.timescale.com/api/latest/continuous-aggregates/create_materialized_view/#create-materialized-view-continuous-aggregate。但是,如文档中所示,连续聚合中不允许使用窗口函数,因此连续聚合无效。

然后,只是把东西扔到墙上,看看什么粘住了,我想知道我是否可以在插入过程中引用前一行

INSERT INTO charge_data VALUES (..., ([$chargevalue]-LAG(charge) OVER (ORDER BY time)), ...);
HINT:  There is a column named "charge" in table "mx_data", but it cannot be referenced from this part of the query.

我知道我可以计算增量

  • 插入前
  • 插入后通过修改每个 charge_data 行及其增量
  • 在 SQL 查询中
  • 在查询程序中

但让数据库在插入时/前后计算一次值似乎更简单、更整洁,这让我怀疑我遗漏了一些东西。有什么方法可以在时间尺度上近实时地计算和存储每一行​​的 charge[battery][n]-charge[battery][n-1] ?


我认为插入前触发器效果很好。您可以创建 before_insert 触发器并在使用先前的引用插入时更新增量 soc。

CREATE TABLE batteries ( time timestamp not null, batt_uid varchar, charge int, delta int);
SELECT create_hypertable('batteries', 'time');

CREATE OR REPLACE FUNCTION update_delta() RETURNS trigger AS
$BODY$
DECLARE
    previous_charge integer; 
BEGIN
   select charge
   into previous_charge
   from batteries where batt_uid = NEW.batt_uid
   order by time desc limit 1;

  IF NEW.charge IS NOT NULL THEN
    IF previous_charge IS NOT NULL THEN
       NEW.delta = NEW.charge - previous_charge;
    ELSE
      NEW.delta = 0;

    END IF;
  END IF;

  RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;

CREATE TRIGGER update_delta_on_insert
               BEFORE INSERT
               ON batteries
               FOR EACH ROW
               EXECUTE PROCEDURE update_delta();

Testing


INSERT INTO batteries VALUES 
('2021-08-26 10:09:00'::timestamp, 'battery-1', 32),
('2021-08-26 10:09:01'::timestamp, 'battery-1', 34),
('2021-08-26 10:09:02'::timestamp, 'battery-1', 38);

INSERT INTO batteries VALUES 
('2021-08-26 10:09:00'::timestamp, 'battery-2', 0),
('2021-08-26 10:09:01'::timestamp, 'battery-2', 4),
('2021-08-26 10:09:02'::timestamp, 'battery-2', 28),
('2021-08-26 10:09:03'::timestamp, 'battery-2', 32),
('2021-08-26 10:09:04'::timestamp, 'battery-2', 28);

输出来自:

SELECT * FROM batteries;

┌─────────────────────┬───────────┬────────┬───────┐
│        time         │ batt_uid  │ charge │ delta │
├─────────────────────┼───────────┼────────┼───────┤
│ 2021-08-26 10:09:00 │ battery-1 │     32 │     0 │
│ 2021-08-26 10:09:01 │ battery-1 │     34 │     2 │
│ 2021-08-26 10:09:02 │ battery-1 │     38 │     4 │
│ 2021-08-26 10:09:00 │ battery-2 │      0 │     0 │
│ 2021-08-26 10:09:01 │ battery-2 │      4 │     4 │
│ 2021-08-26 10:09:02 │ battery-2 │     28 │    24 │
│ 2021-08-26 10:09:03 │ battery-2 │     32 │     4 │
│ 2021-08-26 10:09:04 │ battery-2 │     28 │    -4 │
└─────────────────────┴───────────┴────────┴───────┘
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算 TimescaleDB 中值相对于上次读数的变化 的相关文章

随机推荐

  • urllib 异常 http.client.BadStatusLine

    我一生都无法弄清楚为什么我不能捕获这个异常 看着这里本指南 https docs python org 3 howto urllib2 html def get team names get team id url team id prin
  • 错误 404 的默认重定向

    我想在我的 ASP net 网站中引入一项功能 每当收到对我的域中未知 URL 的请求时 用户就会被重定向到我的网站error 404 htm应用程序根目录中的页面 例如 如果请求是http www mydomain com blahbla
  • System.IO.ReadAllxxx / WriteAllxxx 方法的性能

    是否有 System IO File ReadAllxxx WriteAllxxx 方法与 Web 上提供的 StreamReader StremWriter 类的性能比较 您认为在 net 3 0 中读取 写入文本文件的最佳方式 从性能角
  • Cloud Functions 中的 Cloud Firestore

    我想将新的 Cloud Firestore 集成到我的 Cloud Functions 中 我更新了 node js 并在我的 Mac 上安装了最新的 firebase 版本 文档说 exports myFunctionName funct
  • 如何在 React 应用程序中处理 Firebase onAuthStateChanged 并相应地路由用户?

    我正在开发一个与 Firebase 集成的 React Web 应用程序 并且我正在尝试对我的用户进行身份验证 我已经设置了路线 以便在用户通过身份验证时显示主页组件 否则显示登录页面 但是 当我的应用程序首次加载时 它会显示登录页面 需要
  • 数据框的小提琴图

    我有一个data frame 例如 df data frame AAA rnorm 100 1 1 BBB rnorm 100 2 1 5 CCC rnorm 100 1 5 1 2 我想在联合小提琴图中绘制它的每个列 这是我目前所处的位置
  • 计算 sf 线串与 r 中的网格单元相交的次数

    考虑一组线串和一个多边形网格 sf 几何 library sf creating data example id lt c 844 844 844 844 844 855 855 855 855 855 lat lt c 30 6456 2
  • 大数的质因数分解

    我正在尝试找出大数因式分解的复杂性 哪种算法是最好的 查找数字质因数的复杂度是多少 假设数字的长度为n 最著名的大于 100 位整数因式分解算法是通用数域筛 http en wikipedia org wiki General number
  • VBA代码取消保护打开的powerpoint演示文稿,然后在保存之前再次保护它?

    我保护了 Power Point 演示文稿不被用户修改 但是我无法使用 VBA 取消对其的保护 我尝试使用下面的代码 但它不起作用 它仅适用于未受保护的演示文稿 但您必须从代码中删除密码 set p pa presentations ope
  • 我如何更改 DOCTYPE

    这里有人知道我如何使用 javascript 动态更改文档类型吗 我尝试过这个功能 document doctype 但它不起作用 我希望这可以帮助你们中的一些人 在控制台中测试 它改变了实际的 DOCTYPE var newDoctype
  • 文件名中可以​​使用“/”吗?

    我知道这不是应该做的事情 但是有没有办法使用通常在 Linux 中分隔文件名中的目录的斜杠字符 答案是你不能 除非你的文件系统有错误 原因如下 有一个系统调用用于重命名您定义的文件fs namei c called renameat SYS
  • 如何进行布尔异或?

    显然没有布尔版本的按位异或运算符 该怎么办 这是由不等于运算符提供的 lt gt
  • Razor 语法突出显示在带有 MVC 5 的 VS 2012 中不起作用

    我正在 Visual Studio 2013 RC 中使用 MVC 5 RC 1 效果很好 现在 我按照与描述相同的方式将 VS 2012 中现有的 MVC 4 项目升级到 MVC 5here http egypt silverkeytec
  • 大整数的 GCD 算法

    我正在研究快速 次二次 GCD 计算算法并寻找它们的任何细节 我想看看它们的实现 以便有机会更好地理解它们 Euclid GCD 和 Binary GCD 算法 具有二次运行时间 显然非常简单 我对它们没有任何问题 我正在寻找的算法是 Le
  • X-Macros 的实际使用

    我刚刚了解到X Macros http en wikibooks org wiki C Programming Preprocessor X Macros 您见过 X 宏在现实世界中的哪些用途 它们什么时候是适合这项工作的工具 几年前 当我
  • Spark中是否可以插入临时表?

    我使用 Databricks 和 Apache Spark 2 4 测试了以下查询 sql
  • 解析时间戳以与 CW Log Insights 函数一起使用

    尝试使用内置的 Cloudwatch Log 功能 例如 日期楼层 带有像 2020 03 24T19 03 34 645Z 这样的 8601 时间戳字符串会返回一个 失效日期 Cloudwatch Log Insights 中出现错误 有
  • 在 React Native 中使用 python 库

    我想在 React Native 应用程序中使用一些 Python 库 用于机器学习等 是否可以在不使用服务器的情况下完成此操作 即在移动应用程序中运行 Python 代码 从而不需要互联网 React Native 应用程序由两个主要部分
  • 原子比较、多处理器、C/C++ (Linux)

    我在多台共享内存 x 中有一个变量处理器 system void MyFunction volatile int x if x 0 do something 其他进程 可能在不同的处理器上 将使用 gcc 内置原子操作 例如 sync bo
  • 计算 TimescaleDB 中值相对于上次读数的变化

    我在 TimescaleDB 中存储了有关一组电池的时间序列数据 这些数据记录了每个电池每次的 充电状态 我没有测量流入和流出的流量 只有瞬时充电状态 从这些数据中 我想找到每次充电状态的变化 稍后我将把它存储在几个小时内的消耗中 在做了一