SQL 按时间序列检索所有行的前一行值的总和

问题描述 投票:0回答:2

我的 SQL 生锈了。 我有一个像这样的数据框/表(部分显示,这只是一个示例,不是真实的数据):

+--------------------+-----+---+
|           timestamp|value| id|
+--------------------+-----+---+
|2024-10-05 20:38:...|   67|  0|
|2024-10-05 19:38:...|   14|  1|
|2024-10-05 18:38:...|   80|  2|
|2024-10-05 17:38:...|    6|  3|
+--------------------+-----+---+

用简单的英语来说,我想做的是:假设

id
位于第 0 行。我想要获得一个数据结果集,这样对于第 0 行中的
id
,我返回所有数据的总和在第 0 行中的
value
之前 3 小时的所有行的第
timestamp
列中,并包括第 0 行的
value
。然后,我想对所有行(0 到
n
)执行此操作(其中
n 
行可能很大,约为数亿)。

所以,我的输出将如下所示(稍微截断):

+--------------------+-----+---+
|           timestamp|sum  | id|
+--------------------+-----+---+
|2024-10-05 20:38:...|  167|  0| /* this result is the `value` of the id in row 0, plus the three hours' of previous data */
|2024-10-05 19:38:...|  100|  1| /* this would be more than 100 with the full dataset, etc. */
|2024-10-05 18:38:...|   86|  2|
+--------------------+-----+---+ /* etc etc */

我确定已经有人问过这个问题或变体,但我做了大量研究,但似乎找不到这个问题。 更具体地说,我正在使用 Spark DataFrames,但普通 SQL 也可以。

sql dataframe apache-spark pyspark time-series
2个回答
0
投票

在 SQLite 中你可以这样做

SELECT
  d.timestamp,
  d.value,
  d.id,
  (
    SELECT
      SUM(di.value)
    FROM data di
    WHERE
      di.timestamp BETWEEN datetime(d.timestamp, '-3 hours') AND d.timestamp
  ) AS sum
FROM data d;

不太熟悉 Spark,但谷歌搜索 Spark DataFrames 和“窗口函数”会返回有希望的结果


0
投票

您的帮手是窗口函数。我不熟悉 Apache Spark,但关于文档(https://spark.apache.org/docs/latest/sql-ref-syntax-qry-select-window.html)它应该在这个领域工作就像 Postgresql 一样。

简而言之,窗口函数执行某种数据聚合,无需对行进行分组,而是使用一个计算操作的窗口。如果您正在使用例如sum,然后使用提供的 order by,您将得到一个运行总和,或者在您的情况下得到一个逆运行总和。

select 
ts, value, id,
sum(value) over (order by id desc) as sum
from dataframe order by id;

were

sum(value) over (order by id desc)
是一个窗口函数并提供以下结果:

ts 价值 id 总和
2024-10-05 20:38:00 67 0 167
2024-10-05 19:38:00 14 1 100
2024-10-05 18:38:00 80 2 86
2024-10-05 17:38:00 6 3 6
© www.soinside.com 2019 - 2024. All rights reserved.