对 sql 中相互依赖的两列使用先前记录的算术计算

Arithmetic calculation using previous record for two columns which depends each other in sql

在我的 table 中,我必须计算不同列的值。这些值可以从当前行和上一行到达。这两个列值取决于每个 other.If 我更改一列的值会影响另一列。

我正在分享一个示例table供您参考

A   | B   | C   | D
500 | 400 | 400 | 0
300 | 400 | 300 | 100
200 | 500 | 200 | 400
700 | 200 | 600 | 0
900 | 800 | 800 | 0

在上面table我必须计算C和D列。 Excel公式为:

如何在 sql

中达到相同的结果
CREATE TABLE sampl (A int, B int);
INSERT INTO SAMPL VALUES (500, 400);
INSERT INTO SAMPL VALUES (300, 400);
INSERT INTO SAMPL VALUES (200, 500);
INSERT INTO SAMPL VALUES (700, 200);
INSERT INTO SAMPL VALUES (900, 800);
SELECT * FROM sampl
SELECT *, CASE WHEN A>B THEN B ELSE A END C, CASE WHEN A-B<=0 THEN -1*(A-B) ELSE 0 END D FROM sampl

多条记录如何到达

rn  Tab a   b   c   d    
1   AA  500 400 400 0    
2   AA  300 400 300 100    
3   AA  200 500 200 400    
4   AA  700 200 600 0    
5   AA  900 800 800 0    
1   BB  500 400 400 0    
2   BB  300 400 300 100    
3   BB  200 500 200 400   
4   BB  700 200 600 0

我已将公式转换为递归 CTE:

DECLARE @tbl TABLE (tab VARCHAR(100), rn INT, a INT, b INT);
INSERT INTO @tbl VALUES
('aa', 1, 500, 400),
('aa', 2, 300, 400),
('aa', 3, 200, 500),
('aa', 4, 700, 200),
('aa', 5, 900, 800),
('bb', 1, 500, 400),
('bb', 2, 300, 400),
('bb', 3, 200, 500),
('bb', 4, 700, 200);

WITH rcte AS (
    SELECT tab
         , rn
         , a
         , b
         , IIF(a > b, b, a) AS c
         , IIF(a - b <= 0, -1 * (a - b), 0) AS d
    FROM @tbl
    WHERE rn = 1

    UNION ALL

    SELECT curr.tab
         , curr.rn
         , curr.a
         , curr.b
         , IIF(curr.a > curr.b + prev.d, curr.b + prev.d, curr.a)
         , IIF(curr.a - (curr.b + prev.d) <= 0, -1 * (curr.a - (curr.b + prev.d)), 0)
    FROM @tbl AS curr
    JOIN rcte AS prev ON curr.tab = prev.tab AND curr.rn = prev.rn + 1
)
SELECT *
FROM rcte
ORDER BY tab, rn

请注意,我在数据中添加了 rn 列。如有必要,您可以使用 ROW_NUMBER() OVER (PARTITION BY tab ORDER BY foo) 生成此列。还要注意 a - b <= 0 可以写成 a <= b.

Demo on db<>fiddle