根据前面的公式计算电流
Calculate current based on previous formula
我有一个场景,当前列值是根据公式计算的先前值计算的
组首行没有之前的值所以不考虑
损失公式= relase-withdraw-least(previous_row_loss,reverse)
下面损失是我需要计算的列。
我尝试了以下查询,但没有得到预期的输出。你能在这里指导我吗?
SELECT
pid,release,withdraw,reverse,
SUM(release - withdraw - LEAST( LAG(loss,1,0) OVER (ORDER BY pid)),reverse)) as loss
FROM transactions
您可以使用 MODEL
子句:
SELECT *
FROM (
SELECT t.*,
ROW_NUMBER() OVER (ORDER BY pid, fiscalperiod) AS rn
FROM table_name t
)
MODEL
DIMENSION BY (rn)
MEASURES (pid, fiscalperiod, release, withdraw, reverse, 0 AS loss)
RULES (
loss[1] = release[1] - withdraw[1] - reverse[1],
loss[rn>1] = release[cv()] - withdraw[cv()] - LEAST(reverse[cv()], loss[cv()-1])
+ loss[cv()-1]
);
或者,递归查询的效率可能低得多:
WITH numbered_rows AS (
SELECT t.*,
ROW_NUMBER() OVER (ORDER BY pid, fiscalperiod) AS rn
FROM table_name t
),
recursive_query (rn, pid, fiscalperiod, release, withdraw, reverse, loss) AS (
SELECT rn,
pid,
fiscalperiod,
release,
withdraw,
reverse,
release - withdraw - reverse
FROM numbered_rows
WHERE rn = 1
UNION ALL
SELECT n.rn,
n.pid,
n.fiscalperiod,
n.release,
n.withdraw,
n.reverse,
n.release - n.withdraw + GREATEST(r.loss - n.reverse, 0)
FROM numbered_rows n
INNER JOIN recursive_query r
ON (n.rn = r.rn + 1)
)
SELECT *
FROM recursive_query;
其中,对于您的示例数据:
CREATE TABLE table_name (pid, fiscalperiod, release, withdraw, reverse) AS
SELECT 'A1', 2022001, 10, 10, 10 FROM DUAL UNION ALL
SELECT 'A1', 2022002, 20, 13, 2 FROM DUAL UNION ALL
SELECT 'A1', 2022003, 20, 20, 10 FROM DUAL UNION ALL
SELECT 'A2', 2022002, 15, 10, 13 FROM DUAL;
双输出:
RN
PID
FISCALPERIOD
RELEASE
WITHDRAW
REVERSE
LOSS
1
A1
2022001
10
10
10
-10
2
A1
2022002
20
13
2
7
3
A1
2022003
20
20
10
0
4
A2
2022002
15
10
13
5
db<>fiddle here
我有一个场景,当前列值是根据公式计算的先前值计算的 组首行没有之前的值所以不考虑
损失公式= relase-withdraw-least(previous_row_loss,reverse)
下面损失是我需要计算的列。
我尝试了以下查询,但没有得到预期的输出。你能在这里指导我吗?
SELECT
pid,release,withdraw,reverse,
SUM(release - withdraw - LEAST( LAG(loss,1,0) OVER (ORDER BY pid)),reverse)) as loss
FROM transactions
您可以使用 MODEL
子句:
SELECT *
FROM (
SELECT t.*,
ROW_NUMBER() OVER (ORDER BY pid, fiscalperiod) AS rn
FROM table_name t
)
MODEL
DIMENSION BY (rn)
MEASURES (pid, fiscalperiod, release, withdraw, reverse, 0 AS loss)
RULES (
loss[1] = release[1] - withdraw[1] - reverse[1],
loss[rn>1] = release[cv()] - withdraw[cv()] - LEAST(reverse[cv()], loss[cv()-1])
+ loss[cv()-1]
);
或者,递归查询的效率可能低得多:
WITH numbered_rows AS (
SELECT t.*,
ROW_NUMBER() OVER (ORDER BY pid, fiscalperiod) AS rn
FROM table_name t
),
recursive_query (rn, pid, fiscalperiod, release, withdraw, reverse, loss) AS (
SELECT rn,
pid,
fiscalperiod,
release,
withdraw,
reverse,
release - withdraw - reverse
FROM numbered_rows
WHERE rn = 1
UNION ALL
SELECT n.rn,
n.pid,
n.fiscalperiod,
n.release,
n.withdraw,
n.reverse,
n.release - n.withdraw + GREATEST(r.loss - n.reverse, 0)
FROM numbered_rows n
INNER JOIN recursive_query r
ON (n.rn = r.rn + 1)
)
SELECT *
FROM recursive_query;
其中,对于您的示例数据:
CREATE TABLE table_name (pid, fiscalperiod, release, withdraw, reverse) AS
SELECT 'A1', 2022001, 10, 10, 10 FROM DUAL UNION ALL
SELECT 'A1', 2022002, 20, 13, 2 FROM DUAL UNION ALL
SELECT 'A1', 2022003, 20, 20, 10 FROM DUAL UNION ALL
SELECT 'A2', 2022002, 15, 10, 13 FROM DUAL;
双输出:
RN PID FISCALPERIOD RELEASE WITHDRAW REVERSE LOSS 1 A1 2022001 10 10 10 -10 2 A1 2022002 20 13 2 7 3 A1 2022003 20 20 10 0 4 A2 2022002 15 10 13 5
db<>fiddle here