如何使用窗口函数引用输出行?

Posted

技术标签:

【中文标题】如何使用窗口函数引用输出行?【英文标题】:How to reference output rows with window functions? 【发布时间】:2016-01-06 18:36:49 【问题描述】:

假设我有一个带有quantity 列的表。

CREATE TABLE transfers (
  user_id integer,
  quantity integer,
  created timestamp default now()
);

我想使用窗口函数迭代地遍历分区,但访问输出行,而不是输入表行。

要访问输入表行,我可以这样做:

SELECT LAG(quantity, 1, 0)
  OVER (PARTITION BY user_id ORDER BY created)
FROM transfers;

我需要访问上一个输出行来计算下一个输出行。如何访问输出中的滞后行?比如:

CREATE VIEW balance AS
SELECT LAG(balance.total, 1, 0) + quantity AS total
  OVER (PARTITION BY user_id ORDER BY created)
FROM transfers;

编辑

这是一个支持如何访问窗口分区中的前一个输出行的最小示例。我其实不想要一个总和。

【问题讨论】:

【参考方案1】:

您似乎试图计算running sum。幸运的是,这正是 Sum() 窗口函数所做的:

WITH transfers AS(
    SELECT i, random()-0.3 AS quantity  FROM generate_series(1,100) as i
)
SELECT i, quantity, sum(quantity) OVER (ORDER BY i) from transfers;

【讨论】:

这只是一个例子,我想在case语句和计算中使用之前的输出行。【参考方案2】:

我想,看看这个问题,你唯一需要的就是计算一个累积和。 要计算累积和,请使用以下查询:

SELECT *,
      SUM( CASE WHEN quantity IS NULL THEN 0 ELSE quantity END) 
      OVER ( PARTITION BY user_id ORDER BY created
             ROWS BETWEEN unbounded preceding AND current row
              ) As cumulative_sum
FROM transfers
ORDER BY user_id, created
;

但如果您想要更复杂的计算,尤其是包含一些依赖于前一行结果的条件(决策),那么您需要一种递归方法。

【讨论】:

是的,这只是一个例子,我需要做一些花哨的事情。

以上是关于如何使用窗口函数引用输出行?的主要内容,如果未能解决你的问题,请参考以下文章

如何计算行值相对于其他行值的差异总和,特别是使用窗口函数不包括该行

如何使用窗口函数根据奇偶行号过滤掉结果,没有现有列作为行ID

在窗口函数中如何引用正在定义的列,即引用自身?

Postgres - 如何对窗口函数列的每 x 行求和?

如何在命令行的 telnet 窗口上读取输入和写入输出?

编写一个简单的Java应用程序,该程序在命令行窗口输出数组的引用以及元素的值。