2011-11-22 94 views
1

我有一张表,可以在一分钟内存储有关价格变动的数据。每条记录都包含在最后一分钟的开盘价,最高价,最低价,收市价&卷SQL Server获取组成汇总的第一行和最后一行

CREATE TABLE TimeBar (
    Instrument varchar(20), 
    BarTimeStamp datetimeoffset(7), 
    Open decimal(18, 5), 
    High decimal(18, 5), 
    Low decimal(18, 5), 
    Close decimal(18, 5), 
    Volume int 
) 

我希望能够有什么,我试图做的是创建一个查询在那里我可以汇总数据为更高的时间框架,例如显示开放,高,低&每小时关闭。

以下是我的查询到目前为止,我已经设法得到最高和最低,但你如何获得开放和关闭?

SELECT MIN(BarTimeStamp) AS TimeStamp, 
     MAX(High) AS High, 
     MIN(Low) AS Low, 
     SUM(Volume) AS Volume 
    FROM TimeBar 
    WHERE Instrument = 'XYZ' 
GROUP BY DATEPART(YEAR, BarTimeStamp), DATEPART(MONTH, BarTimeStamp), DATEPART(DAY, BarTimeStamp), DATEPART(HOUR, BarTimeStamp) 

回答

1

使用主查询作为子查询,取每条记录的最小时间戳和最大的时间戳,因此,采取相应的打开和关闭的价格为他们。

SELECT x.*, TI.Open, TE.Close 
FROM 
(
SELECT Instrument, 
     MIN(BarTimeStamp) AS TimeStampIni, 
     MAX(BarTimeStamp) AS TimeStampEnd, 
     MAX(High) AS High, 
     MIN(Low) AS Low, 
     SUM(Volume) AS Volume 
    FROM TimeBar 
GROUP BY Instrument, DATEPART(YEAR, BarTimeStamp), DATEPART(MONTH, BarTimeStamp), DATEPART(DAY, BarTimeStamp), DATEPART(HOUR, BarTimeStamp) 
) x 
inner join TimeBar TI on ti.Instrument = x.Instrument AND TI.BarTimeStamp = x.TimeStampIni 
inner join TimeBar Te on te.Instrument = x.Instrument AND Te.BarTimeStamp = x.TimeStampEnd 
+0

谢谢,正是我之后。 –

1

的第一件事要做的就是用时间组范围:

SELECT MIN(BarTimeStamp) AS StartTimeStamp, 
     MAX(BarTimeStamp) AS EndTimeStamp 
    FROM #TimeBar 
    WHERE Instrument = 'TEST' 
GROUP BY DATEPART(YEAR, BarTimeStamp), DATEPART(MONTH, BarTimeStamp), DATEPART(DAY,  BarTimeStamp), DATEPART(HOUR, BarTimeStamp) 

之后,它的问题:

  • 做了一个连接以获取范围,
  • 做一个加入得到开始
  • 做一个加入得到最小
  • 分组由最初的范围内选择一切

我喜欢使用公共表表达式,使其更容易:

;WITH times as (
    SELECT MIN(BarTimeStamp) AS StartTimeStamp, 
      MAX(BarTimeStamp) AS EndTimeStamp 
     FROM #TimeBar 
     WHERE Instrument = 'TEST' 
    GROUP BY DATEPART(YEAR, BarTimeStamp), DATEPART(MONTH, BarTimeStamp), DATEPART(DAY, BarTimeStamp), DATEPART(HOUR, BarTimeStamp) 
) 
SELECT 
    StartTimeStamp as TimeStamp 
    ,MIN([first].[Open]) as [Open] 
    ,MAX(ranged.High) as High 
    ,MAX(ranged.Low) as Low 
    ,MIN([last].[Close]) as [Close] 
    ,SUM(ranged.Volume) as Volume 
FROM times 
INNER JOIN #TimeBar ranged ON times.StartTimeStamp <= ranged.BarTimeStamp AND times.EndTimeStamp >= ranged.BarTimeStamp 
INNER JOIN #TimeBar [first] ON times.StartTimeStamp = [first].BarTimeStamp 
INNER JOIN #TimeBar [last] ON times.EndTimeStamp = [last].BarTimeStamp 
GROUP BY [times].StartTimeStamp 

这里是我的测试数据:

CREATE TABLE #TimeBar (
    Instrument varchar(20), 
    BarTimeStamp datetimeoffset(7), 
    [Open] decimal(18, 5), 
    High decimal(18, 5), 
    Low decimal(18, 5), 
    [Close] decimal(18, 5), 
    Volume int 
) 

insert into #TimeBar values ('TEST', '2011-11-21 1:00', 5, 6, 4, 8, 100) 
insert into #TimeBar values ('TEST', '2011-11-21 1:10', 1, 7, 3, 4, 100) 
insert into #TimeBar values ('TEST', '2011-11-21 2:10', 15, 16, 17, 18, 100) 
insert into #TimeBar values ('TEST', '2011-11-21 2:30', 12, 16, 17, 19, 100) 
insert into #TimeBar values ('TEST', '2011-11-21 2:50', 13, 14, 15, 20, 100) 

和结果是:

TimeStamp       Open         High         Low          Close         Volume 
---------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- ----------- 
2011-11-21 01:00:00.0000000 +00:00 5.00000         7.00000         4.00000         4.00000         200 
2011-11-21 02:10:00.0000000 +00:00 15.00000        16.00000        17.00000        20.00000        300 

请注意,我为此使用了一个临时表,只需将#TimeBar更改为TimeBar即可将其更改为您的真实表。


另外,我不喜欢看到Instrurment varchar作为字段定义。你应该使用这个surrogate key

相关问题