Postgresql - Запрос с расчетом с использованием предыдущего значения в том же столбце (без циклов) - PullRequest
0 голосов
/ 21 апреля 2020

Я использую Postgresql и немного застрял при вычислении столбца, значение которого зависит от результата предыдущей строки. Я все еще развиваю свои sql навыки с помощью небольших задач за один раз.

Для начала у меня есть таблица:

ID  |  CUSIP    |  datetime             |  price
--------------------------------------------------
200 | 00130H105 | 1991-06-26 05:00:00   |  3.37517
201 | 00130H105 | 1991-06-27 05:00:00   |  3.37517
202 | 00130H105 | 1991-06-28 05:00:00   |  3.396
203 | 00130H105 | 1991-07-01 05:00:00   |  3.41684
204 | 00130H105 | 1991-07-02 05:00:00   |  3.45851
205 | 00130H105 | 1991-07-03 05:00:00   |  3.41684
206 | 00130H105 | 1991-07-05 05:00:00   |  3.29183
207 | 00130H105 | 1991-07-08 05:00:00   |  3.29183

Я пытаюсь рассчитать (5-дневный для этого примера) столбец экспоненциальной скользящей средней (EMA). Значения для первых (5) строк будут нулевыми. Шестая строка будет просто AVG (цена) OVER (ORDER BY DATETIME).

Остальные строки в EMA будут EMA = (цена закрытия сегодня) S + (предыдущая EMA ) (1-S) . Обратите внимание, что S - это константа, которая пока будет жестко задана. Это в конечном итоге будет преобразовано в код многократного использования, где константы будут различаться. Для этого примера S = 0,33.

У меня есть следующий код, который дает мне мое начальное значение EMA, но я застрял, пытаясь вычислить на основе предыдущей строки.

SELECT *
FROM
(WITH STOCKPARTITION AS (
    SELECT ID, CUSIP, DATETIME, price,
    ROW_NUMBER() OVER(PARTITION BY DAILYHIST.CUSIP ORDER BY DAILYHIST.DATETIME) AS K
    FROM DAILYHIST
    WHERE DAILYHIST.CUSIP = '00130H105'
) 
SELECT *, 
 CASE
 WHEN K = 6 THEN AVG(STOCKPARTITION.price) OVER(ORDER BY STOCKPARTITION.datetime ROWS BETWEEN 4 PRECEDING AND CURRENT ROW)
 ELSE NULL
 END AS EMA
 FROM STOCKPARTITION
 ) LIST

Дайте мне что-то вроде:

ID  |  CUSIP    |  datetime             |  price     |  k  |  EMA
-----------------------------------------------------------------
200 | 00130H105 | 1991-06-26 05:00:00   |  3.37517   |  1  | null
201 | 00130H105 | 1991-06-27 05:00:00   |  3.37517   |  2  | null
202 | 00130H105 | 1991-06-28 05:00:00   |  3.396     |  3  | null
203 | 00130H105 | 1991-07-01 05:00:00   |  3.41684   |  4  | null
204 | 00130H105 | 1991-07-02 05:00:00   |  3.45851   |  5  | null
205 | 00130H105 | 1991-07-03 05:00:00   |  3.41684   |  6  | 3.40434
206 | 00130H105 | 1991-07-05 05:00:00   |  3.29183   |  7  | null  <--- not sure how to calculate
207 | 00130H105 | 1991-07-08 05:00:00   |  3.29183   |  8  | null  <--- not sure how to calculate

Я пытаюсь вернуть ту же таблицу, что и выше, и рассчитать две последние строки в столбце EMA. Таким образом, для K = 7 значение EMA должно вычисляться (3.29183) * S + (3.40434) (1 * S). (Примечание S является константой 0,33). Я хотел бы держаться подальше от for-l oop, так как в реальной таблице есть несколько строк для вычисления.

Буду признателен за любую помощь / руководство.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...