如何在SQL

时间:2016-01-11 15:47:29

标签: sql

我将市场数据存储在表格中,格式如下:

Timestamp           Price   Quantity    Condition
01/11/2016 09:03:57 14.34   1           S
01/11/2016 09:03:58 14.31   5   
01/11/2016 09:03:59 14.34   1           S
01/11/2016 09:03:59 14.35   2   
etc.

我想把它分成一分钟长的条,看起来像这样:

BarEndTime          Open    High    Low     Close
01/11/2016 09:03    14.15   14.16   14.13   14.15
01/12/2016 09:04    14.17   14.19   14.17   14.18

如何根据基础数据集的时间戳将此数据分组到一分钟群集中?我在R中相当容易做到这一点,但出于多种原因我也想在SQL中构建它们。

2 个答案:

答案 0 :(得分:1)

我不知道R因此我只能猜出“桶”和“群集”是什么。但是如果,你应该在{em>开放,最小,最大结束每分钟的Price值。间隔然后以下可能会有所帮助:

;WITH cte AS (
 SELECT CONVERT(char(16),Timestamp,126) ts, MIN(Price) p0, MAX(Price) p1,
 MIN(Timestamp) t0, MAX(Timestamp) t1
 FROM #tbl GROUP BY CONVERT(char(16),Timestamp,126)
)
SELECT ts,(SELECT min(Price) FROM #tbl WHERE Timestamp=t0) po,
       p0,p1,
       (SELECT max(Price) FROM #tbl WHERE Timestamp=t1) pc
FROM cte

有关示例,请参阅here

输入:

Timestamp             Price  Qty Cnd
01/11/2016 09:03:57   14.34    1   S
01/11/2016 09:03:58   14.31    5   
01/11/2016 09:03:59   14.34    1   S
01/11/2016 09:03:59   14.35    2   
01/11/2016 09:04:37   11.84    1   S
01/11/2016 09:04:48   12.36    5   
01/11/2016 09:04:49   14.54    1   S
01/11/2016 09:04:59   13.35    2   

输出:

ts               po    p0    p1    pc
2016-01-11T09:03 14.34 14.31 14.35 14.35
2016-01-11T09:04 11.84 11.84 14.54 13.35

由于根据示例数据,对于特定的Price,可能有多个 Timestamp,因为我必须为(SELECT min(Price) FROM #tbl WHERE Timestamp=t0)子查询装备开头和min()/max()汇总函数的收盘价。也许你可以找到一个更好的解决方案来将这些子查询限制为只有一个值的结果。

在我的解决方案中,我使用了一个公用表表达式(CTE),这在某些数据库系统(如MySql)中不可用。因此,如果您使用RDBS 而不使用 CTE,您可以使用简单的子查询轻松地重写上述内容,因为cte仅被引用一次:

SELECT ts,(SELECT min(Price) FROM #tbl WHERE Timestamp=t0) po,p0,p1,
       (SELECT max(Price) FROM #tbl WHERE Timestamp=t1) pc
FROM 
(SELECT CONVERT(char(16),Timestamp,126) ts, MIN(Price) p0, MAX(Price) p1,
 MIN(Timestamp) t0, MAX(Timestamp) t1
 FROM #tbl GROUP BY CONVERT(char(16),Timestamp,126)) subq

答案 1 :(得分:0)

如果您使用的是Oracle:    计算open作为一分钟内首先出现的值(如果在第一个时间戳上多于一个,则最低值,并且在一分钟内关闭为最后一个出现的值(如果多个存在具有相同时间戳的值,则更高的值),分析将成为您的朋友。

with dat as(
SELECT to_Date('01/11/2016 09:03:57','dd/mm/yyyy hh24:mi:ss') ts, 14.34 val,  1 qty,  'S' cond from dual union all
SELECT to_Date('01/11/2016 09:03:58','dd/mm/yyyy hh24:mi:ss') ts, 14.31 val,   5 qty,  null cond from dual union all
SELECT to_Date('01/11/2016 09:03:59','dd/mm/yyyy hh24:mi:ss') ts, 14.34 val,   1qty,   'S' cond from dual union all
SELECT to_Date('01/11/2016 09:03:59','dd/mm/yyyy hh24:mi:ss') ts,  14.35 val,   2 qty, null cond from dual union all  
SELECT to_Date('01/11/2016 09:03:51','dd/mm/yyyy hh24:mi:ss') ts,  14.35 val,   2 qty, null cond from dual union all
SELECT to_Date('01/11/2016 09:04:09','dd/mm/yyyy hh24:mi:ss') ts,  14.45 val,   2 qty, null cond from dual union all  
SELECT to_Date('01/11/2016 09:04:19','dd/mm/yyyy hh24:mi:ss') ts,  14.15 val,   2 qty, null cond from dual union all  
SELECT to_Date('01/11/2016 09:04:29','dd/mm/yyyy hh24:mi:ss') ts,  14.55 val,   2 qty, null cond from dual union all  
SELECT to_Date('01/11/2016 09:04:39','dd/mm/yyyy hh24:mi:ss') ts,  14.85 val,   2 qty, null cond from dual union all  
SELECT to_Date('01/11/2016 09:04:49','dd/mm/yyyy hh24:mi:ss') ts,  14.45 val,   2 qty, null cond from dual union all  
SELECT to_Date('01/11/2016 09:04:59','dd/mm/yyyy hh24:mi:ss') ts,  14.25 val,   2 qty, null cond from dual )
select trunc(ts,'mi') as ts_minute, 
       min (val) keep  (dense_rank first order by ts) as open_val,
       max (val) keep  (dense_rank last order by ts) as close_val,
       min (val) min_val,
       max(val) max_val
from dat
group by trunc(ts,'mi') ;       



 TS_MINUTE,            OPEN_VAL,  CLOSE_VAL,   MIN_VAL,   MAX_VAL
01/11/2016 9:03:00 AM, 14.35,     14.35,       14.31,     14.35
01/11/2016 9:04:00 AM, 14.45,     14.25,       14.15,     14.85