带有“lag()”窗口函数的 PostgreSQL 更新查询
Posted
技术标签:
【中文标题】带有“lag()”窗口函数的 PostgreSQL 更新查询【英文标题】:PostgreSQL update query with "lag()" window function 【发布时间】:2018-02-28 18:52:20 【问题描述】:我有一个涉及 Postgresql 数据库的任务。我对 SQL 不是很熟悉。
我有一张交易产品每周营业额的表格。
每周提供以下信息:产品、周数、周营业额(可能是正数或负数,取决于天气,购买或出售了更多产品)。我添加了一个列,其中包含每周的期末余额。我在表中有第一周所有产品的期末余额(week_number = 0),但对于所有其他周为“null”。下面提供了一些示例性记录。
product | week_number | turnover | closing_balace
--------------------------------+-------------+----------+----------------
BLGWK-05.00*1250*KR-S235JRN0-A | 0 | 50.00 | 1240.00
BLGWK-05.00*1250*KR-S355J2CN-K | 0 | 45.70 | 455.75
BLGWK-05.00*1464*KR-DD11NIET-K | 0 | 30.01 | 300.00
BLGWK-05.00*1500*KR-DD11NIET-R | 1 | 10.22 |
BLGWK-05.00*1500*KR-S235J2CU-K | 1 | 88.00 |
我需要一个查询来使用以下计算填充所有“空”close_balance:
closing_balance = closing_balance of the same product for previous week + turnover for the week.
我试过这个查询:
update table_turnover
set closing_balance = (select lag(closing_balance, 1) over (partition by product order by week_number) + turnover)
where week_number > 0;
它从来没有工作过 - “第 0 周”以上的关闭余额的“空”值仍然是“空”。
我也试过了:
update table_turnover
set closing_balance = (select
case when week_number = 0
then closing_balance
else (lag(closing_balance, 1) over (partition by product order by week_number) + turnover)
end
from table_turnover)
这会产生错误
子查询返回多条记录作为表达式
知道如何进行此计算吗?
提前谢谢你。
【问题讨论】:
【参考方案1】:在from
子句中使用子查询:
update table_turnover
set closing_balance = (ttprev.prev_closing_balance + ttprev.turnover)
from (select tt.*,
lag(closing_balance) over (partition by product order by
week_number) as prev_closing_balance
from table_turnover tt
) ttprev
where ttprev.product = tt.product and ttprev.week_number = tt.week_number and
week_number > 0;
或者,如果您想在select
中使用子查询:
update table_turnover
set closing_balance = (turnover +
(select tt2.closing_balance
from table_turnover tt2
where tt2.product = tt.product and tt2.week_number = tt.week_number - 1
)
)
where week_number > 0;
为了提高性能(在任一版本上),您需要在table_turnover(product, week_number, closing_balance)
上建立索引。
【讨论】:
感谢您的回答。不幸的是,我无法运行查询。它给出了一个错误:“第 3 行中的表 tt 没有 FROM 子句”。知道为什么会这样吗? 好的。我进行了查询,谢谢。不幸的是,它们非常缓慢(执行所有产品需要 DAYS 天)。还有其他想法吗? @Broono 。 . .桌子有多大?无论如何,索引应该可以解决问题。 为什么UPDATEs
按正确的顺序处理行?例如,如果它在第 2 周尚未填满时尝试更新第 3 周,我们将在第 3 周得到NULLs
。 PostgreSQL
由于其版本控制系统和查询计划,不保证表中的任何顺序。
@EvgenyNozdrev 。 . .如果您有问题,请作为问题提出。以上是关于带有“lag()”窗口函数的 PostgreSQL 更新查询的主要内容,如果未能解决你的问题,请参考以下文章
BigQuery 中的 CONDITIONAL_TRUE_EVENT 的替代方案,带有 LAG() 函数?