有没有一个PostgreSQL的SQL函数可以让我存储每一行的结果,以便在下一行中使用?

sqyvllje  于 2023-08-04  发布在  PostgreSQL
关注(0)|答案(2)|浏览(103)

我在PostgreSQL中有下面的表,我想找到一个函数或逻辑,将第一行的结果存储在新列中,然后在第二行中使用,依此类推。
公式是(stock + pending-sells),所以对于第一行,结果是“2”,这应该成为我在第二行的新股票值。结果是2 + 0 + 0 = 2。对于下一行(第3行),我的新股票是(2 + 1 - 0),结果是3,下面的行也是一样。
有没有一种方法可以使用SQL来实现这一点,或者我需要在外部使用Python来尝试?
| 日期,日期|识别码|股票|待定|销售| sells |
| --|--|--|--|--| ------------ |
| 2023-07-01 2023-07-01| 187760|一个|一个|0个| 0 |
| 2023年8月1日|187760|一个|0个|0个| 0 |
| 2023年9月1日|187760|一个|一个|0个| 0 |
| 2023-10-01| 187760|一个|0个|一个| 1 |
| 2023-11-01| 187760|一个|0个|0个| 0 |
| 2023-12-01| 187760|一个|0个|0个| 0 |
我试过lag()和lead(),到目前为止都没有运气。
“预期结果”列,其中包含此表的公式(库存+待定-卖出)
| 日期,日期|识别码|股票|待定|销售|预期结果| expected_results |
| --|--|--|--|--|--| ------------ |
| 2023-07-01 2023-07-01| 187760|一个|一个|0个|二个| 2 |
| 2023年8月1日|187760|二个|0个|0个|二个| 2 |
| 2023年9月1日|187760|二个|一个|0个|三个| 3 |
| 2023-10-01| 187760|三个|0个|一个|二个| 2 |
| 2023-11-01| 187760|二个|0个|0个|二个| 2 |
| 2023-12-01| 187760|二个|0个|0个|二个| 2 |
通过将前一行的计算结果视为下一行的新库存来计算“预期结果”列。
我试过用这个

with cte_ as
(
SELECT 
nc.date,
nc.id,
RANK() OVER (PARTITION BY nc.id ORDER BY nc.date ASC) AS ranking,
nc.stock,
nc.pending,
nc.sells,
nc.stock + nc.pending - nc.sells AS formula
FROM test_table nc 
where nc.id='187760'
)
select *,
lag(c.formula) OVER (PARTITION BY c.id ORDER BY c.date),
lag(c.formula) OVER (PARTITION BY c.id ORDER BY c.date)+c.pending-c.sells as test
from cte_ as c

字符串
但是结果列是
| results |
| ------------ |
| NULL |
| 2 |
| 2 |
| 1 |
| 0 |

  • 谢谢-谢谢
    最好的问候。
ffscu2ro

ffscu2ro1#

在数据库之外进行这样简单的算术计算是没有意义的。
在表中使用值1填充stock列是错误的。如果您仅根据变动重新计算股票,则需要应用变动的起始值。大多数系统使用当前(永续)库存作为起点并向后计算。
我使用它作为初始库存水平与first_value()

select idx, date, id, 
       coalesce(
         first_value(stock) over w1 
           + sum(pending) over w1
           - sum(sells) over w1
         , stock) as stock,
       pending, sells,
       first_value(stock) over w2 
         + sum(pending) over w2
         - sum(sells) over w2 as expected_result
  from test_table
window w1 as (partition by id order by date
              rows between unbounded preceding and 1 preceding),
       w2 as (partition by id order by date);

字符串
工作fiddle

kyvafyod

kyvafyod2#

下面的查询返回原始帖子中显示的结果:

WITH t(idx, date, id, stock, pending, sells) AS (
  VALUES (0, '2023-07-01'::date, 187760, 1, 1, 0),
         (1, '2023-08-01'::date, 187760, 1, 0, 0),
         (2, '2023-09-01'::date, 187760, 1, 1, 0),
         (3, '2023-10-01'::date, 187760, 1, 0, 1),
         (4, '2023-11-01'::date, 187760, 1, 0, 0),
         (5, '2023-12-01'::date, 187760, 1, 0, 0))
SELECT idx, date, id, stock, pending, sells,
       stock + sum(pending) OVER stock_group - sum(sells) OVER stock_group AS expected_results
  FROM t
  WINDOW stock_group AS (PARTITION BY id ORDER BY idx)
  ORDER BY idx;

字符串
此查询使用sum作为窗口函数,其隐式窗口框架为ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,以聚合pendingsells,并将其添加到当前stock
本查询涉及修订后的职位:

WITH t(idx, date, id, stock, pending, sells) AS (
  VALUES (0, '2023-07-01'::date, 187760, 1, 1, 0),
         (1, '2023-08-01'::date, 187760, 1, 0, 0),
         (2, '2023-09-01'::date, 187760, 1, 1, 0),
         (3, '2023-10-01'::date, 187760, 1, 0, 1),
         (4, '2023-11-01'::date, 187760, 1, 0, 0),
         (5, '2023-12-01'::date, 187760, 1, 0, 0))
SELECT idx, date, id,
       stock + coalesce(sum(pending) OVER stock_group_prior - sum(sells) OVER stock_group_prior, 0) AS stock,
       pending, sells,
       stock + coalesce(sum(pending) OVER stock_group_current - sum(sells) OVER stock_group_current, 0) AS expected_results
  FROM t
  WINDOW stock_group_prior AS (PARTITION BY id ORDER BY idx ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING),
         stock_group_current AS (PARTITION BY id ORDER BY idx)
  ORDER BY idx;

相关问题