Разница между значениями в разных строках в зависимости от времени - PullRequest
0 голосов
/ 29 марта 2020

MariaDB версия 10.4.10.

У меня есть скрипт скребка, который каждый час выбирает данные о запасах и вставляет их в базу данных MySQL. Мне нужен способ получить разницу цен для каждой акции, например:

  • акций, выбранных в 2020-03-25 07:00 и 2020-03-25 19:00 (12 часов)
  • акций, полученных в 2020-03-25 07:00 и 2020-03-26 07:00 (24 часа)
  • акций, полученных в 2020-03-25 08:00 и 2020-03 -25 20:00 (12 часов)
  • акции, выбранные в 2020-03-25 08:00 и 2020-03-26 08:00 (24 часа) et c

Структура базы данных выглядит примерно так:

stocks( time_fetched DATETIME, name VARCHAR, price INT )

Некоторые примеры данных:

**time_fetched          name        price**
2020-03-25 07:00:00     stock_A     10
2020-03-25 07:00:00     stock_B     14
2020-03-25 08:00:00     stock_A     12
2020-03-25 08:00:00     stock_B     20
...
2020-03-25 19:00:00     stock_A     28
2020-03-25 19:00:00     stock_B     32
2020-03-25 20:00:00     stock_A     40
2020-03-25 20:00:00     stock_B     36
...
2020-03-26 07:00:00     stock_A     12
2020-03-26 07:00:00     stock_B     16
2020-03-26 08:00:00     stock_A     18
2020-03-26 08:00:00     stock_B     16

Ожидаемый результат:

**time_fetched            name        current_price     price_12h_ago     price_24h_ago**
2020-03-25 19:00:00     stock_A     28                10                NULL
2020-03-25 19:00:00     stock_B     32                14                NULL
2020-03-25 20:00:00     stock_A     40                12                NULL
2020-03-25 20:00:00     stock_B     36                20                NULL
2020-03-26 07:00:00     stock_A     12                28                10
2020-03-26 07:00:00     stock_B     16                32                14
2020-03-26 08:00:00     stock_A     18                40                12
2020-03-26 08:00:00     stock_B     16                36                20

В настоящее время я использую SQL похоже на это:

WITH prices AS (
  SELECT time_fetched, name, price,
         LAG(price, 12) OVER(PARTITION BY name ORDER BY time_fetched) AS price_12h_ago,
         LAG(price, 24) OVER(PARTITION BY name ORDER BY time_fetched) AS price_24h_ago
  FROM stocks
)
SELECT time_fetched, name, price AS current_price, price_12h_ago, price_24h_ago
FROM prices

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

Это означает, что приведенный выше код выбирает цену на 12 строк до текущей, не всегда соответствует 12 часам до текущей строки.

Так что мне нужен способ получить разницу в цене на основе фактического времени.

Надеюсь, что это имеет хоть какой-то смысл для всех:)

1 Ответ

0 голосов
/ 29 марта 2020

Вы можете использовать предложение range(). Если ваше время точное:

SELECT time_fetched, name, price,
       MIN(price) OVER (PARTITION BY name
                        ORDER BY time_fetched
                        RANGE BETWEEN INTERVAL 12 hour AND INTERVAL 12 hour
                       ) as price_12h_ago,
       MIN(price) OVER (PARTITION BY name
                        ORDER BY time_fetched
                        RANGE BETWEEN INTERVAL 24 hour AND INTERVAL 24 hour
                       ) as price_24h_ago
FROM stocks;

Если вы не установите минуты и секунды равными 0, вам может потребоваться более широкий диапазон, чем мгновение. Например:

SELECT time_fetched, name, price,
       MIN(price) OVER (PARTITION BY name
                        ORDER BY time_fetched
                        RANGE BETWEEN INTERVAL '12:05' HOUR_MINUTE AND INTERVAL '11:55' HOUR_MINUTE
                       ) as price_12h_ago,
       MIN(price) OVER (PARTITION BY name
                        ORDER BY time_fetched
                        RANGE BETWEEN INTERVAL '24:05' HOUR_MINUTE AND INTERVAL '23:55' HOUR_MINUTE
                       ) as price_24h_ago
FROM stocks;
...