Sql 基于两个不同行中的值进行计算
我在MS Access中有一张表,它的股价排列如下Sql 基于两个不同行中的值进行计算,sql,vba,ms-access,Sql,Vba,Ms Access,我在MS Access中有一张表,它的股价排列如下 Ticker1, 9:30:00, $49.01 Ticker1, 9:30:01, $49.08 Ticker2, 9:30:00, $102.02 Ticker2, 9:30:01, $102.15 等等 我需要做一些计算,其中我需要将一行中的价格与前一行的价格进行比较,如果价格在1秒内的变化大于X%,我需要单独报告该实例 如果我在Excel中这样做,这是一个相当简单的公式。我有几百万行数据,所以这不是一个选项 有没有关于如何在MS A
Ticker1, 9:30:00, $49.01
Ticker1, 9:30:01, $49.08
Ticker2, 9:30:00, $102.02
Ticker2, 9:30:01, $102.15
等等
我需要做一些计算,其中我需要将一行中的价格与前一行的价格进行比较,如果价格在1秒内的变化大于X%,我需要单独报告该实例
如果我在Excel中这样做,这是一个相当简单的公式。我有几百万行数据,所以这不是一个选项
有没有关于如何在MS Access中执行此操作的建议
我对任何有或没有SQL或VBA的解决方案都持开放态度
更新:
最后,我尝试在嵌套循环中使用ADODB.Recordset遍历我的记录。代码如下。我认为这是一个好主意,对于一个20k行的小表格来说,逻辑是有效的。但是当我在一个更大的表上运行它时,由于临时表的原因,访问量膨胀到2GB限制而没有完成任务,原始表的大小更像~300MB。将其发布在此处,以防它对具有较小数据集的用户有所帮助
Do While Not rstTickers.EOF
myTicker = rstTickers!ticker
rstDates.MoveFirst
Do While Not rstDates.EOF
myDate = rstDates!Date_Only
strSql = "select * from Prices where ticker = """ & myTicker & """ and Date_Only = #" & myDate & "#" 'get all prices for a given ticker for a given date
rst.Open strSql, cn, adOpenKeyset, adLockOptimistic 'I needed to do this to open in editable mode
rst.MoveFirst
sPrice1 = rst!Open_Price
rst!Row_Num = i
rst.MoveNext
Do While Not rst.EOF
i = i + 1
rst!Row_Num = i
rst!Previous_Price = sPrice1
sPrice2 = rst!Open_Price
rst!Price_Move = Round(Abs((sPrice2 / sPrice1) - 1), 6)
sPrice1 = sPrice2
rst.MoveNext
Loop
i = i + 1
rst.Close
rstDates.MoveNext
Loop
rstTickers.MoveNext
Loop
如果数据总是相隔一秒而没有任何毫秒,那么您可以在Ticker ID上将表连接到自身,并将时间偏移一秒 否则,如果没有某种类型的序列计数器可以连接,则需要创建一个。您可以通过执行排名查询来实现这一点。对此有多种方法。你可以试试每一个,看看哪一个在你的情况下工作得最快 一种方法是使用子查询返回当前行之前的行数。另一种方法是在表前面的所有行上将表连接到它自己,并执行GROUPBY和count。这两种方法产生相同的结果,但取决于数据的性质、数据的结构和索引,一种方法比另一种方法更快
一旦有了排名列,您就可以执行第一段中描述的过程,但不是按时间偏移量加入,而是按排名偏移量加入。我最终将数据移动到了一个有自己问题的SQL server。我添加了一个row number变量row_num,如下所示
ALTER TABLE Prices ADD Row_Num INT NOT NULL IDENTITY (1,1)
我想这对我来说是有效的,因为我的基础数据符合我需要的顺序。我已经读了足够多的评论,您不应该这样做,因为您不知道服务器存储数据的顺序
无论如何,在那之后,它本身就是一个连接。我花了一段时间才弄明白我对SQL不熟悉的语法。在此处添加SQL以供参考适用于SQL server,但不适用于Access
Update A Set Previous_Price = B.Open_Price
FROM Prices A INNER JOIN Prices B
ON A.Date_Only = B.Date_Only
WHERE ((A.Ticker=B.Ticker) AND (A.Row_Num=B.Row_Num+1));
顺便说一句,我必须先添加Date_列,这样只适用于Access,而不适用于SQL server
UPDATE Prices SET Prices.Date_Only = Format([Time_Date],"mm/dd/yyyy");
我认为@Rabbit描述的行号的解决方案从广义上讲应该更有效。我只是没有时间尝试一下。我花了整整一天的时间才走到这一步。Ticker1和Ticker2在同一排吗?还是每行都以Ticker开头?对于样本数据来说是非常好的/BrokenRecord@CSS,该表有3列。股票行情、时间、价格。我有多个时间段的多个股票的价格。谢谢。我喜欢你的第一个建议,做一个连接本身,除了我意识到不是每一个股票交易每秒,所以有情况下,我只有一个9:30:00,然后9:30:05排。您能否共享一个返回当前行之前的行数的子查询示例?选择t1.date,从表中选择COUNT*作为t2,其中t1.date