对 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公式为:
- C 的第 1 行是 IF(A2>B2,B2,A2)
- C 的第 2 行到最后一行是 IF(A3>B3+D2,B3+D2,A3)
- D 的第一行是 IF(A2-B2<=0,-1*(A2-B2),0)
- D 的第二行到最后一行是 IF(A3-(B3+D2)<=0,-1*(A3-(B3+D2)),0)
如何在 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
.
在我的 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公式为:
- C 的第 1 行是 IF(A2>B2,B2,A2)
- C 的第 2 行到最后一行是 IF(A3>B3+D2,B3+D2,A3)
- D 的第一行是 IF(A2-B2<=0,-1*(A2-B2),0)
- D 的第二行到最后一行是 IF(A3-(B3+D2)<=0,-1*(A3-(B3+D2)),0)
如何在 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
.