Один из приемов для получения первых и последних значений в MySql 5.x - это объединение GROUP_CONCAT
(с заказом по) & SUBSTRING_INDEX
.
Пример:
SELECT
symbol,
FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP (`timestamp`)/300)*300) AS `timestamp`,
CAST(SUBSTRING_INDEX(GROUP_CONCAT(`open` ORDER BY `timestamp` ASC SEPARATOR '|'),'|',1) AS DECIMAL(10,2)) AS `open`,
MAX(`high`) AS `high`,
MIN(`low`) AS `low`,
CAST(SUBSTRING_INDEX(GROUP_CONCAT(`close` ORDER BY `timestamp` DESC SEPARATOR '|'),'|',1) AS DECIMAL(10,2)) AS `close`
FROM ohlc_database
WHERE symbol LIKE 'AMBUJACEM'
GROUP BY symbol, FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP (`timestamp`)/300)*300);
Результат:
symbol timestamp open high low close
--------- ------------------- ------ ------ ------ ------
AMBUJACEM 24.01.2019 03:45:00 213,10 213,5 213,1 213,50
AMBUJACEM 24.01.2019 03:50:00 213,70 213,8 212 212,40
AMBUJACEM 24.01.2019 03:55:00 212,40 212,75 211,85 211,90
В MySql 8 вы также можете использовать оконную функцию FIRST_VALUE
для этого.
SELECT
symbol,
ts05 as `timestamp`,
MIN(first_open) as `open`,
MAX(`high`) as `high`,
MIN(`low`) as `low`,
MAX(last_close) as `close`
FROM
(
SELECT
id, symbol, `timestamp`, `low`, `high`,
FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP (`timestamp`)/300)*300) AS ts05,
FIRST_VALUE(`open`) OVER (PARTITION BY symbol, FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP (`timestamp`)/300)*300) ORDER BY `timestamp` ASC) as first_open,
FIRST_VALUE(`close`) OVER (PARTITION BY symbol, FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP (`timestamp`)/300)*300) ORDER BY `timestamp` DESC) AS last_close
FROM ohlc_database
WHERE symbol LIKE 'AMBUJACEM'
) q
GROUP BY symbol, ts05;
Тест по дБ <> скрипка здесь