gpt4 book ai didi

sql - 滚动总和直到达到某个值,加上计算的持续时间

转载 作者:行者123 更新时间:2023-11-29 11:40:04 26 4
gpt4 key购买 nike

我有一个要求,我需要知道 sum(value) 何时达到特定点并计算持续时间。下面是示例表。

create table sample (dt timestamp, value real);

insert into sample values
('2019-01-20 00:29:43 ',0.29)
,('2019-01-20 00:35:06 ',0.31)
,('2019-01-20 00:35:50 ',0.41)
,('2019-01-20 00:36:32 ',0.26)
,('2019-01-20 00:37:20 ',0.33)
,('2019-01-20 00:41:30 ',0.42)
,('2019-01-20 00:42:28 ',0.35)
,('2019-01-20 00:43:14 ',0.52)
,('2019-01-20 00:44:18 ',0.25);

现在我的要求是计算以下行的累计总和,以查看 sum(value) 何时达到 1.0 以上。这可能只需要 1 行或 n 行。到达该行后,我需要计算当前行与 sum(value) 达到 1.0 以上的行之间的时间差。

基本上我想要的输出格式如下。
对于第 1 行,累积 sum(value) 在第 3 行达到。
对于第 2 行,累计 sum(value) 达到第 4 行等。

         dt         | value | sum(value)| time_at_sum(value)_1| Duration
---------------------+--------+------------------------------------------
2019-01-20 00:29:43| 0.29 | 1.01 | 2019-01-20 00:35:50 | 00:06:07
2019-01-20 00:35:06| 0.31 | 1.31 | 2019-01-20 00:37:20 | 00:02:14
2019-01-20 00:35:50| 0.41 | 1.00 | 2019-01-20 00:37:20 | 00:01:30
2019-01-20 00:36:32| 0.26 | 1.01 | 2019-01-20 00:41:30 | 00:04:58
2019-01-20 00:37:20| 0.33 | 1.10 | 2019-01-20 00:42:28 | 00:05:08
2019-01-20 00:41:30| 0.42 | 1.29 | 2019-01-20 00:43:14 | 00:01:44
2019-01-20 00:42:28| 0.35 | 1.12 | 2019-01-20 00:44:18 | 00:01:50
2019-01-20 00:43:14| 0.52 | NULL | - | -
2019-01-20 00:44:18| 0.25 | NULL | - | -

有人对如何处理上述要求有想法或指示吗?

最佳答案

WITH tmp AS (
SELECT *
, sum(value) OVER (ORDER BY dt rows between current row and unbounded following) as forward_sum
FROM sample
ORDER BY dt)
SELECT t1.dt, t1.value
, (t2.value + t1.forward_sum - t2.forward_sum) as "sum(value)"
, t2.dt as "time_at_sum(value)_1"
, t2.dt - t1.dt as "Duration"
FROM tmp t1
LEFT JOIN LATERAL (
SELECT *
FROM tmp t
WHERE t1.forward_sum - t.forward_sum < 1
AND (t.value + t1.forward_sum - t.forward_sum) >= 0.999
ORDER BY dt DESC
LIMIT 1
) t2
ON TRUE

产量

| dt                  | value | sum(value) | time_at_sum(value)_1 | Duration |
|---------------------+-------+------------+----------------------+----------|
| 2019-01-20 00:29:43 | 0.29 | 1.01 | 2019-01-20 00:35:50 | 00:06:07 |
| 2019-01-20 00:35:06 | 0.31 | 1.31 | 2019-01-20 00:37:20 | 00:02:14 |
| 2019-01-20 00:35:50 | 0.41 | 1 | 2019-01-20 00:37:20 | 00:01:30 |
| 2019-01-20 00:36:32 | 0.26 | 1.01 | 2019-01-20 00:41:30 | 00:04:58 |
| 2019-01-20 00:37:20 | 0.33 | 1.1 | 2019-01-20 00:42:28 | 00:05:08 |
| 2019-01-20 00:41:30 | 0.42 | 1.29 | 2019-01-20 00:43:14 | 00:01:44 |
| 2019-01-20 00:42:28 | 0.35 | 1.12 | 2019-01-20 00:44:18 | 00:01:50 |
| 2019-01-20 00:43:14 | 0.52 | | | |
| 2019-01-20 00:44:18 | 0.25 | | | |

首先计算 value 列的累计和:

SELECT *
, sum(value) OVER (ORDER BY dt rows between current row and unbounded following) as forward_sum
FROM sample
ORDER BY dt

产生

| dt                  | value | forward_sum |
|---------------------+-------+-------------|
| 2019-01-20 00:29:43 | 0.29 | 3.14 |
| 2019-01-20 00:35:06 | 0.31 | 2.85 |
| 2019-01-20 00:35:50 | 0.41 | 2.54 |
| 2019-01-20 00:36:32 | 0.26 | 2.13 |
| 2019-01-20 00:37:20 | 0.33 | 1.87 |
| 2019-01-20 00:41:30 | 0.42 | 1.54 |
| 2019-01-20 00:42:28 | 0.35 | 1.12 |
| 2019-01-20 00:43:14 | 0.52 | 0.77 |
| 2019-01-20 00:44:18 | 0.25 | 0.25 |

请注意,从 forward_sum 中减去两个值对应于 value 的部分和。例如,

0.29 + 0.31 + 0.41 = 3.14 - 2.13

因此 forward_sums 的差异将发挥重要作用,我们希望将这些差异与 1 进行比较。我们将希望使用加入条件如下:

t1.forward_sum - t.forward_sum < 1

让我们看看如果我们使用 LEFT JOIN LATERAL 会发生什么。了解 LEFT JOIN LATERAL 的关键是 LATERAL 连接右侧的子查询 has to be evaluated once for each row in the table on the left :

WITH tmp AS (
SELECT *
, sum(value) OVER (ORDER BY dt rows between current row and unbounded following) as forward_sum
FROM sample
ORDER BY dt)
SELECT t1.*, t2.*
FROM tmp t1
LEFT JOIN LATERAL (
SELECT *
FROM tmp t
WHERE t1.forward_sum - t.forward_sum < 1
ORDER BY dt DESC
LIMIT 1
) t2
ON TRUE

产量

| dt                  | value | forward_sum | dt                  | value | forward_sum |
|---------------------+-------+-------------+---------------------+-------+-------------|
| 2019-01-20 00:29:43 | 0.29 | 3.14 | 2019-01-20 00:35:50 | 0.41 | 2.54 |
| 2019-01-20 00:35:06 | 0.31 | 2.85 | 2019-01-20 00:37:20 | 0.33 | 1.87 |
| 2019-01-20 00:35:50 | 0.41 | 2.54 | 2019-01-20 00:37:20 | 0.33 | 1.87 |
| 2019-01-20 00:36:32 | 0.26 | 2.13 | 2019-01-20 00:41:30 | 0.42 | 1.54 |
| 2019-01-20 00:37:20 | 0.33 | 1.87 | 2019-01-20 00:42:28 | 0.35 | 1.12 |
| 2019-01-20 00:41:30 | 0.42 | 1.54 | 2019-01-20 00:43:14 | 0.52 | 0.77 |
| 2019-01-20 00:42:28 | 0.35 | 1.12 | 2019-01-20 00:44:18 | 0.25 | 0.25 |
| 2019-01-20 00:43:14 | 0.52 | 0.77 | 2019-01-20 00:44:18 | 0.25 | 0.25 |
| 2019-01-20 00:44:18 | 0.25 | 0.25 | 2019-01-20 00:44:18 | 0.25 | 0.25 |

请注意,我们已经猜到了符合条件的连接条件想要的日期。现在只需将正确的值表达式组合到获取所需的列,sum(value)time_at_sum(value)_1

关于sql - 滚动总和直到达到某个值,加上计算的持续时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54916984/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com