在计算中使用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 列和后两列的前两条记录,想得到最后两列的其余部分 STOCK
和 WAUC
。
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
注意:ROW
、IN
和 OUT
是关键字,您不应将它们用作标识符,因为在它们出现的任何地方都必须使用带引号的标识符.
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
我想要获得库存和加权平均单位成本 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 列和后两列的前两条记录,想得到最后两列的其余部分 STOCK
和 WAUC
。
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
注意:ROW
、IN
和 OUT
是关键字,您不应将它们用作标识符,因为在它们出现的任何地方都必须使用带引号的标识符.
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