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 join должен оцениваться один раз для каждой строки в таблице слева :
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
.
.