我在表格中以类似的格式存储了一分钟到一分钟的财务记录,
dt | open | high | low | close | vol
---------------------+----------+----------+----------+----------+-------
2018-05-04 15:30:00 | 171.0000 | 171.3000 | 170.9000 | 171.0000 | 42817
2018-05-04 15:29:00 | 170.8000 | 171.0000 | 170.8000 | 170.9500 | 32801
2018-05-04 15:28:00 | 170.8500 | 171.0000 | 170.8000 | 170.8000 | 22991
2018-05-04 15:27:00 | 170.8500 | 170.8500 | 170.7500 | 170.8000 | 40283
2018-05-04 15:26:00 | 170.9500 | 171.0000 | 170.8000 | 170.8500 | 46636
等等。
我想把它们分成5分钟,10分钟,60分钟的块,就像烛台一样。使用date_trunc('hour', dt)
是不可能的,因为我想将它们分组为最后60分钟,最后15分钟等等。
我正在使用PostgreSQL。
答案 0 :(得分:3)
您应该使用GROUP BY
:
floor(extract('epoch' from dt) / 300)
让您的数据以5分钟为间隔进行分组。 300是5分钟内的秒数。因此,如果您想要10分钟,则除以600.如果您想要1小时,则需要3600分钟。
如果您希望时间间隔从00 05 10开始,请使用floor()
。如果您希望它们在00,05,10完成,请使用ceil()
在SELECT
子句中,您应该使用
GROUP BY
中使用的 Unix纪元重新转换为时间戳
to_timestamp(floor((extract('epoch' from dt) / 300)) * 300) as ts
不清楚你是否想要所有的"阻止"导致相同的查询,如果你想要一个烛台图,我假设是。我还逻辑推断了每个列的正确聚合函数(MIN,MAX,AVG,SUM),它们的名称如下。你可能需要调整它。
我们走了:
SELECT '5 minutes' as block,
to_timestamp(floor((extract('epoch' from dt) / 300)) * 300) as ts,
round(AVG(open),4) as avg_open,
round(MAX(high),4) as max_high,
round(MIN(low),4) as min_low,
round(AVG(close),4) as avg_close,
SUM(vol) as sum_vol
FROM mytable
GROUP BY floor(extract('epoch' from dt) / 300)
UNION ALL
SELECT '10 minutes' as block,
to_timestamp(floor((extract('epoch' from dt) / 600)) * 600) as ts,
round(AVG(open),4) as avg_open,
round(MAX(high),4) as max_high,
round(MIN(low),4) as min_low,
round(AVG(close),4) as avg_close,
SUM(vol) as sum_vol
FROM mytable
GROUP BY floor(extract('epoch' from dt) / 600)
UNION ALL
SELECT '1 hour' as block,
to_timestamp(floor((extract('epoch' from dt) / 3600)) * 3600) as ts,
round(AVG(open),4) as avg_open,
round(MAX(high),4) as max_high,
round(MIN(low),4) as min_low,
round(AVG(close),4) as avg_close,
SUM(vol) as sum_vol
FROM mytable
GROUP BY floor(extract('epoch' from dt) / 3600)
结果:
block ts avg_open max_high min_low avg_close sum_vol
5 minutes 04.05.2018 17:30:00 171 171,3 170,9 171 42817
5 minutes 04.05.2018 17:25:00 170,8625 171 170,75 170,85 142711
10 minutes 04.05.2018 17:20:00 170,8625 171 170,75 170,85 142711
10 minutes 04.05.2018 17:30:00 171 171,3 170,9 171 42817
1 hour 04.05.2018 17:00:00 170,89 171,3 170,75 170,88 185528
上测试
答案 1 :(得分:0)
您可以使用generate_series()
创建您想要的任何范围
SELECT dd as start_range, dd + '30 min'::interval as end_range
FROM generate_series
( '2018-05-05'::timestamp
, '2018-05-06'::timestamp
, '30 min'::interval) dd
;
然后检查您的记录是否属于该范围。