我有一个表,其中包含历史外汇历史1分钟水平数据,我想根据1分钟水平数据选择10分钟数据。
我的表格如下所示:
ccy Time open high low close
AUDUSD 2018.03.26 00:00 0.77282 0.77283 0.77265 0.77265
AUDUSD 2018.03.26 00:01 0.77264 0.77266 0.77261 0.77266
AUDUSD 2018.03.26 00:02 0.77264 0.77265 0.77259 0.77264
AUDUSD 2018.03.26 00:03 0.77262 0.77262 0.7726 0.77262
AUDUSD 2018.03.26 00:04 0.77262 0.77262 0.77262 0.77262
AUDUSD 2018.03.26 00:05 0.7726 0.7726 0.7726 0.7726
AUDUSD 2018.03.26 00:06 0.77259 0.77262 0.77259 0.77261
AUDUSD 2018.03.26 00:07 0.77262 0.77265 0.77262 0.77264
AUDUSD 2018.03.26 00:08 0.77263 0.77272 0.77262 0.77272
AUDUSD 2018.03.26 00:09 0.77273 0.77278 0.77271 0.77274
AUDUSD 2018.03.26 00:10 0.77273 0.77282 0.77271 0.77279
AUDUSD 2018.03.26 00:11 0.77282 0.77293 0.77281 0.77291
AUDUSD 2018.03.26 00:12 0.77291 0.77293 0.77287 0.77287
AUDUSD 2018.03.26 00:13 0.77288 0.77288 0.77288 0.77288
AUDUSD 2018.03.26 00:14 0.77288 0.77288 0.77277 0.77279
AUDUSD 2018.03.26 00:15 0.77278 0.77279 0.77255 0.77262
AUDUSD 2018.03.26 00:16 0.77261 0.77271 0.77261 0.77271
AUDUSD 2018.03.26 00:17 0.77271 0.77273 0.77264 0.77271
AUDUSD 2018.03.26 00:18 0.77273 0.77282 0.77273 0.77281
AUDUSD 2018.03.26 00:19 0.77281 0.77285 0.77281 0.77283
您可以看到时间戳是每1分钟一次,而上面是20分钟的数据样本。
我的预期结果是:
ccy Time open high low close
AUDUSD 2018.03.26 00:00 0.77282 0.77283 0.77259 0.77274
AUDUSD 2018.03.26 00:10 0.77273 0.77293 0.77255 0.77283
开盘价必须是时间跨度中每个起点的开盘价,例如从2018.03.26 00:00到2018.03.26 00:09,起点是2018.03.26 00:00 ,因此预期结果开放时间为2018.03.26 00:00的开放时间,即0.77282。
收盘价必须是时间跨度的每个结束点的收盘价,例如从2018.03.26 00:00到2018.03.26 00:09,结束点是2018.03.26 00:09 ,因此预期结果收盘价为2018.03.26 00:09的收盘价,即0.77274。
上限必须是时间跨度的最大值。在高位列中,从2018.03.26 00:00到2018.03.26 00:09,最大值是0.77283,所以我的预期高位是0.77283。
下限必须是时间跨度的最小值。在最低列中,从2018.03.26 00:00到2018.03.26 00:09,最小值为0.77259,所以我的预期最低值为0.77259。
我希望当我有更多数据时,它可以继续循环播放。因此,例如,如果我有1个小时的数据,当我将数据聚合为10分钟的数据时,我希望有60/10 = 6行记录。
我已经为此工作了一段时间,但找不到合适的解决方案,请有人帮忙吗?太谢谢你了!
答案 0 :(得分:1)
有许多问题尚不清楚。这看起来像是货币换算数据,但未在问题(ccy?)中说明,并且您似乎希望按ccy进行汇总,但未在问题中说明,因此没有表明您希望传递给查询的内容(间隔范围,间隔类型等)。但首先,这是一种方法的示例,我看到的关键问题是获取第一个和最后一个值
drop table if exists t;
create table t(ccy varchar(6),Tm datetime,open decimal(10,5),high decimal(10,5), low decimal(10,5), close decimal(10,5));
insert into t values
( 'AUDUSD', '2018-03-26 00:00' , 0.77282 , 0.77283 , 0.77265 , 0.77265),
( 'AUDUSD', '2018-03-26 00:01' , 0.77264 , 0.77266 , 0.77261 , 0.77266),
( 'AUDUSD', '2018-03-26 00:02' , 0.77264 , 0.77265 , 0.77259 , 0.77264),
( 'AUDUSD', '2018-03-26 00:03' , 0.77262 , 0.77262 , 0.7726 , 0.77262),
( 'AUDUSD', '2018-03-26 00:04' , 0.77262 , 0.77262 , 0.77262 , 0.77262),
( 'AUDUSD', '2018-03-26 00:05' , 0.7726 , 0.7726 , 0.7726 , 0.7726),
( 'AUDUSD', '2018-03-26 00:06' , 0.77259 , 0.77262 , 0.77259 , 0.77261),
( 'AUDUSD', '2018-03-26 00:07' , 0.77262 , 0.77265 , 0.77262 , 0.77264),
( 'AUDUSD', '2018-03-26 00:08' , 0.77263 , 0.77272 , 0.77262 , 0.77272),
( 'AUDUSD', '2018-03-26 00:09' , 0.77273 , 0.77278 , 0.77271 , 0.77274),
( 'AUDUSD', '2018-03-26 00:10' , 0.77273 , 0.77282 , 0.77271 , 0.77279);
select ccy, (select open from t t1 where t1.ccy = t.ccy order by t1.tm asc limit 1) periodopen,
(select close from t t1 where t1.ccy = t.ccy order by t1.tm desc limit 1) period_close,
max(high) period_high,
min(low) period_low
from t
where t.tm between '2018-03-26 00:00' and '2018-03-26 00:10:00'
group by ccy;
+--------+------------+--------------+-------------+------------+
| ccy | periodopen | period_close | period_high | period_low |
+--------+------------+--------------+-------------+------------+
| AUDUSD | 0.77282 | 0.77279 | 0.77283 | 0.77259 |
+--------+------------+--------------+-------------+------------+
1 row in set (0.00 sec)
答案 1 :(得分:0)
一种方法是对记录进行分组,并使用函数来检索有关每个组的信息。问题是您没有任何要分组的列。
在这种情况下,要在10分钟内创建记录组,可以将“时间”列转换为字符串,并截断最后一位,例如。如果您忽略最后一位,则表中有10条记录的值将为'2018.03.26 00:0'。
关于open
和close
列,您需要从组内的第一行和最后一行获取值。 Mysql没有FIRST
或LAST
聚合函数,但是我从answer中学到了可以使用GROUP_CONCAT
模拟它们。
select
ccy,
SUBSTRING(DATE_FORMAT(Time, '%Y.%m.%d %H:%i'),1,15) as time_group,
SUBSTRING_INDEX(GROUP_CONCAT(CAST(open AS CHAR) ORDER BY Time), ',', 1 ) as open,
MAX(high) as high,
MIN(low) as low,
SUBSTRING_INDEX(GROUP_CONCAT(CAST(close AS CHAR) ORDER BY Time DESC), ',', 1 ) as close
from table_name
group by ccy, time_group;
这是结果
+--------+-----------------+---------+---------+---------+---------+
| ccy | time_group | open | high | low | close |
+--------+-----------------+---------+---------+---------+---------+
| AUDUSD | 2018.03.26 00:0 | 0.77282 | 0.77283 | 0.77259 | 0.77274 |
| AUDUSD | 2018.03.26 00:1 | 0.77273 | 0.77293 | 0.77255 | 0.77283 |
+--------+-----------------+---------+---------+---------+---------+
答案 2 :(得分:0)
这是一项工作-在mssql上测试(我没有mysql),但可能对您有帮助。在mysql中,您只能在字符串concat中更改 TOP 1 , DATEPART 和“ + ”符号。
CREATE TABLE [dbo].[T1](
[F_CCY] [varchar](20) NULL,
[F_TIME] [datetime] NULL,
[F_OPEN] [numeric](10, 8) NULL,
[F_HIGH] [numeric](10, 8) NULL,
[F_LOW] [numeric](10, 8) NULL,
[F_CLOSE] [numeric](10, 8) NULL
);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26', 0.77282, 0.77283, 0.77265, 0.77265);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:01:00', 0.77264, 0.77266, 0.77261, 0.77266);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:02:00', 0.77264, 0.77265, 0.77259, 0.77264);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:03:00', 0.77262, 0.77262, 0.7726, 0.77262);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:04:00', 0.77262, 0.77262, 0.77262, 0.77262);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:05:00', 0.7726, 0.7726, 0.7726, 0.7726);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:06:00', 0.77259, 0.77262, 0.77259, 0.77261);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:07:00', 0.77262, 0.77265, 0.77262, 0.77264);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:08:00', 0.77263, 0.77272, 0.77262, 0.77272);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:09:00', 0.77273, 0.77278, 0.77271, 0.77274);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:10:00', 0.77273, 0.77282, 0.77271, 0.77279);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:11:00', 0.77282, 0.77283, 0.77265, 0.77265);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:12:00', 0.77264, 0.77266, 0.77261, 0.77266);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:13:00', 0.77264, 0.77265, 0.77259, 0.77264);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:14:00', 0.77262, 0.77262, 0.7726, 0.77262);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:15:00', 0.77262, 0.77262, 0.77262, 0.77262);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:16:00', 0.7726, 0.7726, 0.7726, 0.7726);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:17:00', 0.77259, 0.77262, 0.77259, 0.77261);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:18:00', 0.77262, 0.77265, 0.77262, 0.77264);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:19:00', 0.77263, 0.77272, 0.77262, 0.77272);
INSERT INTO T1 (F_CCY, F_TIME, F_OPEN, F_HIGH, F_LOW, F_CLOSE) VALUES('AUDUSD', '2018-03-26 00:20:00', 0.77273, 0.77278, 0.77271, 0.77274);
SELECT
T.F_ccy as "ccy"
, MIN(T.F_TIME) as "Time"
,
(SELECT
TOP 1 FIRST_VALUE(X.F_OPEN) OVER(ORDER BY X.F_TIME)
FROM
T1 X
WHERE
X.F_ccy=T.F_ccy
AND X.F_TIME>=CAST(CAST(CAST(T.F_TIME AS DATE) AS VARCHAR(10)) + ' ' + CAST(DATEPART(HOUR, T.F_TIME) AS VARCHAR(2)) + ':' + CAST((DATEPART(MINUTE, T.F_TIME)/10)*10 AS VARCHAR(2)) AS DATETIME)
AND X.F_TIME<CAST(CAST(CAST(T.F_TIME AS DATE) AS VARCHAR(10)) + ' ' + CAST(DATEPART(HOUR, T.F_TIME) AS VARCHAR(2)) + ':' + CAST(((DATEPART(MINUTE, T.F_TIME)/10)+1)*10 AS VARCHAR(2)) AS DATETIME)
) AS "open"
,
(SELECT
TOP 1 LAST_VALUE(X.F_OPEN) OVER(ORDER BY X.F_TIME)
FROM
T1 X
WHERE
X.F_ccy=T.F_ccy
AND X.F_TIME>=CAST(CAST(CAST(T.F_TIME AS DATE) AS VARCHAR(10)) + ' ' + CAST(DATEPART(HOUR, T.F_TIME) AS VARCHAR(2)) + ':' + CAST((DATEPART(MINUTE, T.F_TIME)/10)*10 AS VARCHAR(2)) AS DATETIME)
AND X.F_TIME<CAST(CAST(CAST(T.F_TIME AS DATE) AS VARCHAR(10)) + ' ' + CAST(DATEPART(HOUR, T.F_TIME) AS VARCHAR(2)) + ':' + CAST(((DATEPART(MINUTE, T.F_TIME)/10)+1)*10 AS VARCHAR(2)) AS DATETIME)
) AS "close"
, MAX(T.F_HIGH) as "high"
, MIN(T.F_LOW) as "low"
FROM
T1 T
GROUP BY
T.F_ccy
, CAST(T.F_TIME AS DATE)
, DATEPART(HOUR, T.F_TIME)
, DATEPART(MINUTE, T.F_TIME)/10