在计算中使用oracle LAG函数数据

Use oracle LAG function data in calculations

我想要获得库存和加权平均单位成本 WAUC

TABLE T1:

ROW ITEM IN OUT PRICE STOCK WAUC
1 A 1000 - 20 1000 20
2 A 2000 - 25 - -
3 A 1500 - 15 - -
4 A 500 - 20 - -

我有前 5 列和后两列的前两条记录,想得到最后两列的其余部分 STOCKWAUC

WAUC = ((PREVIOUS_PRICE * PREVIOUS_STOCK) + (CURRENT_IN * CURRENT_PRICE)) / CURRENT_STOCK

所以,我写查询:

SELECT ROW,
       SUM(IN - OUT) OVER(ORDER BY ROW) STOCK,
       ((LAG(STOCK * WAUC) OVER (ORDER BY ROW)) + (IN * PRICE)) / STOCK AS WAUC
FROM T1

我想要的是:

ROW ITEM IN OUT PRICE STOCK WAUC
1 A 1000 - 20 1000 20
2 A 2000 - 25 3000 23.33
3 A 1500 - 15 4500 20.55
4 A 500 - 20 5000 20.49

也就是说,我想在计算数据中使用LAG个结果。

你的公式应该是:

WAUC = (
         PREVIOUS_WAUC * PREVIOUS_STOCK
       + (CURRENT_IN - CURRENT_OUT) * CURRENT_PRICE
       )
       / CURRENT_STOCK

您可以使用 MODEL 子句(使用一些额外的测量值来简化计算):

SELECT "ROW", item, "IN", "OUT", price, stock, wauc
FROM   t1
MODEL
  DIMENSION BY ("ROW")
  MEASURES (item, "IN", "OUT", price, 0 AS change, 0 AS stock, 0 AS total, 0 AS wauc)
  RULES (
    change["ROW"] = COALESCE("IN"[cv()], 0) - COALESCE("OUT"[cv()], 0),
    stock["ROW"]  = change[cv()] + COALESCE(stock[cv()-1], 0),
    total["ROW"]  = change[cv()] * price[cv()] + COALESCE(total[cv()-1], 0),
    wauc["ROW"]   = total[cv()] / stock[cv()]
);

或者,从 Oracle 12 开始,使用 MATCH_RECOGNIZE:

SELECT "ROW",
       item,
       "IN",
       "OUT",
       price,
       total_stock AS stock,
       total_cost / total_stock AS wauc
FROM   t1
MATCH_RECOGNIZE(
  ORDER BY "ROW"
  MEASURES
    SUM(COALESCE("IN", 0) - COALESCE("OUT", 0)) AS total_stock,
    SUM((COALESCE("IN", 0) - COALESCE("OUT", 0))*price) AS total_cost
  ALL ROWS PER MATCH
  PATTERN (all_rows+)
  DEFINE
    all_rows AS 1 = 1
)

或解析函数:

SELECT "ROW",
       item,
       "IN",
       "OUT",
       price,
       SUM(COALESCE("IN",0) - COALESCE("OUT", 0)) OVER (ORDER BY "ROW")
         AS stock,
       SUM((COALESCE("IN",0) - COALESCE("OUT", 0))*price) OVER (ORDER BY "ROW")
        / SUM(COALESCE("IN",0) - COALESCE("OUT", 0)) OVER (ORDER BY "ROW")
        AS wauc
FROM   t1

其中,对于示例数据:

CREATE TABLE t1 ("ROW", ITEM, "IN", "OUT", PRICE, STOCK, WAUC) AS
SELECT 1, 'A', 1000, CAST(NULL AS NUMBER), 20, CAST(NULL AS NUMBER), CAST(NULL AS NUMBER) FROM DUAL UNION ALL
SELECT 2, 'A', 2000, NULL, 25, NULL, NULL FROM DUAL UNION ALL
SELECT 3, 'A', 1500, NULL, 15, NULL, NULL FROM DUAL UNION ALL
SELECT 4, 'A',  500, NULL, 20, NULL, NULL FROM DUAL;

全部输出:

ROW ITEM IN OUT PRICE STOCK WAUC
1 A 1000 20 1000 20
2 A 2000 25 3000 23.33333333333333333333333333333333333333
3 A 1500 15 4500 20.55555555555555555555555555555555555556
4 A 500 20 5000 20.5

注意:ROWINOUT 是关键字,您不应将它们用作标识符,因为在它们出现的任何地方都必须使用带引号的标识符.

db<>fiddle here

您的问题与“延迟”无关。

使用 MT0 的示例数据:

select "ROW", item, "IN", "OUT", price,
       sum(nvl("IN", 0) - nvl("OUT", 0)) 
           over (partition by item order by "ROW") as stock,
       round(sum((nvl("IN", 0) - nvl("OUT", 0)) * price)
           over (partition by item order by "ROW") 
       / sum(nvl("IN", 0) - nvl("OUT", 0))
           over (partition by item order by "ROW"), 2 ) as wauc
from   t1
;

   ROW ITEM     IN    OUT  PRICE  STOCK   WAUC
------ ---- ------ ------ ------ ------ ------
     1 A      1000            20   1000     20
     2 A      2000            25   3000  23.33
     3 A      1500            15   4500  20.56
     4 A       500            20   5000   20.5