SQL 负值求和直到满足条件(看到正值),然后重新开始求和
SQL sum of negative values until condition (positive value is seen) is met, then restart the summation
我想获得负行值的总和,直到出现正值(这里是下面 table 中的列更改)。
在列中出现另一个负值后,总和应再次开始累积负行值,直到出现另一个正值,依此类推。
鉴于以下 table:
+─────+─────────+─────────────────────────+
| id | change | start_time |
+─────+─────────+─────────────────────────+
| B | -7.4 | 2022-05-21 11:59:54.0 |
| A | -0.8 | 2022-05-21 22:48:47.0 |
| A | -61.5 | 2022-05-22 09:25:22.0 |
| B | -5.3 | 2022-05-22 11:32:14.0 |
| A | -0.3 | 2022-05-22 12:18:49.0 |
| B | -0.1 | 2022-05-22 12:44:05.0 |
| B | -0.5 | 2022-05-22 12:55:38.0 |
| B | -7.2 | 2022-05-22 13:10:20.0 |
| B | 0.0 | 2022-05-22 13:55:04.0 |
| B | 34.8 | 2022-05-22 13:55:54.0 |
| A | 0.0 | 2022-05-22 15:31:47.0 |
| A | -0.1 | 2022-05-22 15:57:19.0 |
| A | 0.0 | 2022-05-22 15:58:17.0 |
| A | -0.1 | 2022-05-22 17:51:38.0 |
| A | 8.1 | 2022-05-22 17:55:01.0 |
| A | -1.9 | 2022-05-22 17:57:26.0 |
| A | 0.0 | 2022-05-22 18:06:03.0 |
| A | 10.1 | 2022-05-22 18:06:08.0 |
| A | -3.0 | 2022-05-22 20:34:26.0 |
+─────+─────────+─────────────────────────+
期望的结果应显示按 id 排序的每个总和的总负值:
+─────+─────────+
| id | change |
+─────+─────────+
| B | -20.5 |
| A | -62.8 |
| A | -1.9 |
| A | -3 |
+─────+─────────+
到目前为止,在看到第一个正值后,我只设法生成了 运行ning 个正值和负值。由于 B 的最后一个值为正,因此总和为 Null。 A 的第一个总和显示 5.19 总结所有(正负)值直到结束。但是,在检测到下一个正值之前,总和应该只 运行,并且应该只对负值求和。
+─────+────────────────────+
| id | total_neg_change |
+─────+────────────────────+
| B | null |
| A | 5.199999999999999 |
| A | -3.0 |
+─────+────────────────────+
此输出是通过 运行以下代码实现的:
SELECT id, total_neg_change
FROM(
SELECT
id,
change,
SUM(change) OVER(PARTITION BY id ORDER BY start_time ASC ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING ) AS total_neg_change
FROM test_table)
WHERE change > 0
我假设“无限跟随”创造了累计和。我怎样才能改变它以获得上面我想要的结果?
这是一个缺口和岛屿问题,其中每个岛屿都是通过具有相同的 id
以及连续的负数来定义的。这是一种方法:
WITH cte AS (
SELECT *, SUM(change > 0) OVER (PARTITION BY id ORDER BY start_time) grp
FROM yourTable
)
SELECT id, SUM(change) AS total_neg_change
FROM cte
WHERE change < 0
GROUP BY id, grp
ORDER BY MIN(start_time);
我想获得负行值的总和,直到出现正值(这里是下面 table 中的列更改)。 在列中出现另一个负值后,总和应再次开始累积负行值,直到出现另一个正值,依此类推。 鉴于以下 table:
+─────+─────────+─────────────────────────+
| id | change | start_time |
+─────+─────────+─────────────────────────+
| B | -7.4 | 2022-05-21 11:59:54.0 |
| A | -0.8 | 2022-05-21 22:48:47.0 |
| A | -61.5 | 2022-05-22 09:25:22.0 |
| B | -5.3 | 2022-05-22 11:32:14.0 |
| A | -0.3 | 2022-05-22 12:18:49.0 |
| B | -0.1 | 2022-05-22 12:44:05.0 |
| B | -0.5 | 2022-05-22 12:55:38.0 |
| B | -7.2 | 2022-05-22 13:10:20.0 |
| B | 0.0 | 2022-05-22 13:55:04.0 |
| B | 34.8 | 2022-05-22 13:55:54.0 |
| A | 0.0 | 2022-05-22 15:31:47.0 |
| A | -0.1 | 2022-05-22 15:57:19.0 |
| A | 0.0 | 2022-05-22 15:58:17.0 |
| A | -0.1 | 2022-05-22 17:51:38.0 |
| A | 8.1 | 2022-05-22 17:55:01.0 |
| A | -1.9 | 2022-05-22 17:57:26.0 |
| A | 0.0 | 2022-05-22 18:06:03.0 |
| A | 10.1 | 2022-05-22 18:06:08.0 |
| A | -3.0 | 2022-05-22 20:34:26.0 |
+─────+─────────+─────────────────────────+
期望的结果应显示按 id 排序的每个总和的总负值:
+─────+─────────+
| id | change |
+─────+─────────+
| B | -20.5 |
| A | -62.8 |
| A | -1.9 |
| A | -3 |
+─────+─────────+
到目前为止,在看到第一个正值后,我只设法生成了 运行ning 个正值和负值。由于 B 的最后一个值为正,因此总和为 Null。 A 的第一个总和显示 5.19 总结所有(正负)值直到结束。但是,在检测到下一个正值之前,总和应该只 运行,并且应该只对负值求和。
+─────+────────────────────+
| id | total_neg_change |
+─────+────────────────────+
| B | null |
| A | 5.199999999999999 |
| A | -3.0 |
+─────+────────────────────+
此输出是通过 运行以下代码实现的:
SELECT id, total_neg_change
FROM(
SELECT
id,
change,
SUM(change) OVER(PARTITION BY id ORDER BY start_time ASC ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING ) AS total_neg_change
FROM test_table)
WHERE change > 0
我假设“无限跟随”创造了累计和。我怎样才能改变它以获得上面我想要的结果?
这是一个缺口和岛屿问题,其中每个岛屿都是通过具有相同的 id
以及连续的负数来定义的。这是一种方法:
WITH cte AS (
SELECT *, SUM(change > 0) OVER (PARTITION BY id ORDER BY start_time) grp
FROM yourTable
)
SELECT id, SUM(change) AS total_neg_change
FROM cte
WHERE change < 0
GROUP BY id, grp
ORDER BY MIN(start_time);