我试图在StockData表上进行OHCL sql查询(SQL Server 2012)。每天有数千行添加到表中,我想获得每天的Open,High,Low和Close数据。
create table sql如下:
CREATE TABLE [dbo].[StockData](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[StockExchangeID] [bigint] NOT NULL,
[DataDateTime] [datetime] NOT NULL,
[ExportCost] [bigint] NOT NULL,
CONSTRAINT [PK_StockData] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
使用下面的查询,我可以获得高,低和平均,但我很难获得当天的ExportCost的Open(最早的ExportCost基于DataDateTime)和Close(基于DataDateTime的最新ExportCost)。
到目前为止,我的查询如下。如果有更有效的方法,那么欢迎任何建议。
DECLARE @IntervalDays INT, @StartDate DATETIME, @EndDate DATETIME;
SET @IntervalDays = 1;
SET @StartDate = '01/01/2017'
SET @EndDate = '01/01/2018'
-- Create the database table
SELECT
StockExchangeID,
DATEADD(DAY, DATEDIFF(DAY,0,[DataDateTime]) / @IntervalDays * @IntervalDays, 0) AS [DateDay],
MAX(ExportCost) AS DayHigh,
MIN(ExportCost) AS DayLow,
AVG(ExportCost) AS DayAverage,
'??????????' As DayOpen, --Not sure how to get the start price for the day i.e. ExportCost for the first record for that day based on [DataDateTime]
'??????????' As DatClose
FROM StockData
WHERE [DataDateTime] >= @StartDate AND [DataDateTime] <= @EndDate
GROUP BY DATEADD(DAY, DATEDIFF(DAY,0,[DataDateTime]) / @IntervalDays * @IntervalDays, 0), StockExchangeID
ORDER BY [DateDay]
答案 0 :(得分:3)
对于旧版本的SQL Server,可以使用相关的子查询:
SELECT
StockExchangeID,
DATEADD(DAY, DATEDIFF(DAY,0,[DataDateTime]) / @IntervalDays * @IntervalDays, 0) AS [DateDay],
MAX(ExportCost) AS DayHigh,
MIN(ExportCost) AS DayLow,
AVG(ExportCost) AS DayAverage,
(SELECT TOP 1 DO.ExportCost FROM StockData AS DO WHERE DO.[DataDateTime] = MIN( A.[DataDateTime] ) ORDER BY ID ASC ) As DayOpen,
(SELECT TOP 1 DC.ExportCost FROM StockData AS DC WHERE DC.[DataDateTime] = MAX( A.[DataDateTime] ) ORDER BY ID DESC ) As DatClose
FROM StockData AS A
WHERE [DataDateTime] >= @StartDate AND [DataDateTime] <= @EndDate
GROUP BY DATEADD(DAY, DATEDIFF(DAY,0,[DataDateTime]) / @IntervalDays * @IntervalDays, 0), StockExchangeID
ORDER BY [DateDay]
注意: Order By ID
用于以防您拥有超过1条相同日期的记录。
对于较新版本,请查看有关FIRST_VALUE
答案 1 :(得分:2)
相信我 - 您可能希望保留此级别的详细数据,但您不希望将其用于一般报告目的。您需要将定价汇总到每天的高/低/收盘/开盘价值并存储它们,因为它们在交易日结束后不会改变(好吧,有时候它们确实如此,但它非常罕见并且不会改变一般方法)。
更进一步 - 您选择主键和聚簇索引可能不是特别有用。您几乎总是在此表中搜索给定的安全性或给定的日期(或日期范围)。在标识列上进行聚类可能很浪费。我还会考虑将日期和时间分成不同的列。日期部分非常重要 - 时间部分可能没有太多使用。如果您要分开日期和时间,您的查询会变得更加简单,因为您只需按日期分组以查找最小值/最大值。通过额外的架构更改(或更好 - 使用后交易聚合表)可以简化查找打开和关闭。