One of the tricks to get the first & last values in MySql 5.x is to combine GROUP_CONCAT
(with an order by) & SUBSTRING_INDEX
.
Example:
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);
Result:
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
In MySql 8, you could also use the window function FIRST_VALUE
for this.
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;
A test on db<>fiddle here
open
andclose
columns (such assum
,avg
, etc) or defining them as well in yourgroup by
statement. By the way - what are the outputs you are getting? – ymz