来自过程性编程,我正在考虑使用循环来解决这个问题.示例逻辑:

  • column1值和日期列降序排序.查询类似于:
select * 
from table1 
where column1 in ('cpu1') 
order by date_time desc;
  • 找到SELECT查询中的最后一行以及它上面的第22行,以定义要查看的第一组数据的循环起点.我目前没有序列化这些行,但知道每个行条目之间的时间是5分钟,所以我可以使用时间戳来确定22行.我认为该查询类似于:
select * 
from table1 
where date_time between x and y;
  • 找到在BETWEEN语句中 Select 的数据中的第10行,并确定第10行中的第2列是否大于上面的所有12行,以及第3列第10行是否比上面的所有12行都大,或者第3列第10行是否小于上面的12行和第9行.如果大于或小于,则将第10行打印到新表.

我还没有关于这个查询的任何东西,因为我不知道如何以使用Java脚本数组或Python字典的方式导航表索引.

  • 递增x、y和第10行值-1并再次运行循环.

The problem

我正在努力理解如何将PostgreSQL脚本组合在一起.我也曾用Python或Java脚本设计过类似的样式循环,但我越是阅读有关如何在SQL中使用它的可能方法,我就越困惑.最理想的CTE方式是For、While还是一个游标?

示例表数据:

column1 column2 column3 date
cpu1 3.2 1.1 01:45:00
cpu1 3.5 1.3 01:40:00
cpu1 5.9 0.1 01:35:00
cpu1 1.7 1.2 01:30:00
cpu1 2.5 2.3 01:25:00
cpu1 5.2 4.1 01:20:00
cpu3 4.2 1.1 01:45:00
cpu3 3.1 1.0 01:40:00
cpu3 5.0 3.3 01:35:00
cpu3 4.7 3.2 01:30:00
cpu3 2.7 2.1 01:25:00
cpu3 6.2 4.8 01:20:00
  • column1将是将时间序列写入数据库的设备名称
  • column2column3将从设备中记录值
  • 日期将始终以5分钟为增量
  • 表1有数百万行

推荐答案

这可以通过窗口函数优雅而高效地实现:

对于所有设备:

SELECT *
FROM  (
   SELECT *, col2 > max(col2) OVER (PARTITION BY device ORDER BY ts ROWS BETWEEN 12 PRECEDING AND 9 FOLLOWING EXCLUDE CURRENT ROW)
          OR col3 < min(col3) OVER (PARTITION BY device ORDER BY ts ROWS BETWEEN 12 PRECEDING AND 9 FOLLOWING EXCLUDE CURRENT ROW) AS bingo
   FROM   tbl
   ) sub
WHERE  bingo;

对于单个给定设备:

SELECT *
FROM  (
   SELECT *
        , col2 > max(col2) OVER (ORDER BY ts ROWS BETWEEN 12 PRECEDING AND 9 FOLLOWING EXCLUDE CURRENT ROW) OR
          col3 < min(col3) OVER (ORDER BY ts ROWS BETWEEN 12 PRECEDING AND 9 FOLLOWING EXCLUDE CURRENT ROW) AS bingo
   FROM   tbl
   WHERE  device = 'cpu3'
   ) sub
WHERE  bingo;

fiddle

假设所有列都定义为NOT NULL,并且时间戳(在我的查询中为ts)也是每个设备UNIQUE.或者,您必须定义如何按排序顺序处理空值和重复项.

这使用了一整套高级窗口函数功能."帧排除"选项EXCLUDE CURRENT ROW需要Postgres 11或更高版本.Read the manual here.个相关主题:

如果您习惯了过程性语言,这不是一项容易的任务.

Sql相关问答推荐

在postgresql中使用来自另一个字段的日期名称作为JSONB查询中的关键字

Oracle SQL中的累计总数

SQL查询以创建手头的流动余额?

如何查询一个名称是根据PL/pgSQL函数结果构建的表?

无法找到正确的SQL查询需求

在多个柱上连接时,如何确定连接条件?

当交叉联接3个或更多表时,实体框架中是否会传输冗余的行数据并占用数据库带宽?

PostgreSQL中的合并命令是原子的,还是需要一些类似于SQL Server版本的内容?

MariaDB查询在逗号分隔的字符串中查找多个值

Access中执行INSERT INTO查询时出现错误消息

从数据库中查找总和大于或等于查询中的数字的数字

Postgres SQL查询从字符串中获取邮箱地址

将用户授予另一个用户不授予权限

我需要在 ASP.NET C# 中获取 2 个 SQL 查询结果的平均值

POSTGRES to_timestamp() 假定 UTC 字符串为本地时间

Oracle PL/SQL长期运行问题

如何创建一个递归计数器来查找一个元素有多少父级和子级?

如何通过存储过程将 root 的下一个子 node 作为父 node ?

sql count distinct by column 和 sum false 和 true

SQL中所有先前日期的累计总和