如何通过mysql获取组中的第一条,最大,最小,最后一条记录

时间:2019-01-27 12:08:12

标签: mysql sql

有人能帮我知道从开列开始的第一条记录,从高位开始的最大值,从低位开始的最小值,以及每隔5分钟间隔格式分组的关闭列的最后一条记录

https://drive.google.com/open?id=1HMDECnuReJbnmRj0o_Gevn1ePMdpDoNy

OHLC Data

我尝试了以下查询间隔智能分组依据

mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);

预期输出 This is my expected output

enter image description here

3 个答案:

答案 0 :(得分:1)

在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;

db <>小提琴here

的测试

答案 1 :(得分:0)

发布的数据集似乎不同。无论如何,这有帮助吗?

SELECT FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(`timestamp`)/300)*300) x FROM ohlc_database;
+---------------------+
| x                   |
+---------------------+
| 2019-01-24 03:45:00 |
| 2019-01-24 03:45:00 |
| 2019-01-24 03:45:00 |
| 2019-01-24 03:45:00 |
| 2019-01-24 03:45:00 |
| 2019-01-24 03:50:00 |
| 2019-01-24 03:50:00 |
| 2019-01-24 03:50:00 |
| 2019-01-24 03:50:00 |
| 2019-01-24 03:50:00 |
| 2019-01-24 03:55:00 |
| 2019-01-24 03:55:00 |
| 2019-01-24 03:55:00 |
| 2019-01-24 03:55:00 |
| 2019-01-24 03:55:00 |
+---------------------+

答案 2 :(得分:0)

使用子查询获取每个周期和符号的最小和最大时间戳。然后使用条件聚合来捕获那些时间戳上的值。

SELECT UNIX_TIMESTAMP(timestamp) DIV 300 as ts,
       symbol,
       MAX(CASE WHEN timestamp = min_ts THEN open END) as open,
       MAX(high) as high,
       MIN(low) as low,
       MAX(CASE WHEN timestamp = max_ts THEN close END) as close
FROM ohlc_database o JOIN
     (SELECT symbol, 
             UNIX_TIMESTAMP(timestamp) DIV 300 as ts,
             MIN(timestamp) as min_ts, MAX(timestamp) as max_ts
      FROM ohlc_database
      WHERE symbol LIKE 'AMBUJACEM' 
      GROUP BY symbol, UNIX_TIMESTAMP(timestamp) DIV 300
     ) o2
     ON o2.ts = UNIX_TIMESTAMP(o.timestamp) DIV 300 AND
        o2.symbol = o.symbol
WHERE symbol LIKE 'AMBUJACEM' 
GROUP BY UNIX_TIMESTAMP(timestamp) DIV 300, symbol