简体   繁体   English

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

[英]How to get first, max, min, last records in a group by with mysql

can anyone help me to know first record from open column, max of from high, min of from low, and last record from close column with 5 minutes interval format group 谁能帮我知道打开列的第一条记录,最高记录的最大值,最低记录的最小值以及关闭列的最后记录(间隔为5分钟)

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

OHLC数据

I tried the below query for interval wise group by 我尝试了下面的间隔明智的分组查询

SELECT
    timestamp,
    symbol,
    open,
    MAX(high) as high,
    MIN(low) as low,
    close
FROM ohlc_database 
WHERE `symbol` LIKE 'AMBUJACEM' 
GROUP BY 
UNIX_TIMESTAMP(timestamp) DIV 300, symbol

Expected Output 预期产量 这是我的预期输出

在此处输入图片说明

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 . 在MySql 5.x中获取第一个和最后一个值的技巧之一是将GROUP_CONCAT (按顺序排列)和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. 在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;

A test on db<>fiddle here dB的测试<>小提琴这里

The posted dataset appears to be different. 发布的数据集似乎不同。 Anyway, does this help: 无论如何,这是否有帮助:

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 |
+---------------------+

Use a subquery to get the minimum and maximum timestamps for each each period and symbol. 使用子查询来获取每个周期和符号的最小和最大时间戳。 Then use conditional aggregation to capture the values at those timestamp. 然后使用条件聚合来捕获那些时间戳上的值。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM