我正在尝试进行JOIN查询来分析一些股票。在我的第一张名为top10perday
的表中,我列出了我每天选择“买入”并在第二天卖出的10只股票:
date symbol
07-Aug-08 PM
07-Aug-08 HNZ
07-Aug-08 KFT
07-Aug-08 MET
...
08-Aug-08 WYE
08-Aug-08 XOM
08-Aug-08 SGP
08-Aug-08 JNJ
例如,记录#1:
我的股票价格在一张名为prices
的表格中,如下所示:
date symbol price
07-Aug-08 PM 54.64
08-Aug-08 PM 55.21
11-Aug-08 PM 55.75
12-Aug-08 PM 55.95
... many more records with trading day, symbol, price
我想做一个JOIN,以便我的结果集如下所示:
date symbol price-next-day price-two-days
07-Aug-08 PM 55.21 55.75
...
list one record per date and symbol in table1.
我尝试过这样的事情:
SELECT top10perday.date, top10perday.symbol, Min(prices.date) AS MinOfdate
FROM prices INNER JOIN top10perday ON prices.symbol = top10perday.symbol
GROUP BY top10perday.date, top10perday.symbol
HAVING (((Min(prices.date))>[date]));
我尝试了很多这方面的变体,但我显然没有在正确的路径上,因为结果集在我的top10perday
表中显示的最早日期中只包含10行。
我正在使用Microsoft Access。在此先感谢您的帮助! : - )
答案 0 :(得分:2)
此语法在Access 2003中有效:
SELECT t10.Date, t10.Symbol, p1.date, p1.price, p2.date, p2.price
FROM
(top10perday AS t10
LEFT JOIN prices AS p1
ON t10.Symbol = p1.symbol)
INNER JOIN prices AS p2 ON t10.Symbol = p2.symbol
WHERE (
((p1.date)=((Select Min([date]) as md
from prices
where [date]>t10.[Date] and symbol = t10.symbol
))
) AND ((p2.date)=((Select Min([date]) as md
from prices
where [date]>p1.[Date] and symbol = t10.symbol)
))
);
这个想法是让第一个(最小)日期大于上一个表格中的日期(top10perday,价格为p1)
答案 1 :(得分:1)
我的猜测是:
SELECT top10perday.date, top10perday.symbol, MIN(pnd.price) AS PriceNextDay, MIN(ptd.price) AS PriceTwoDays
FROM top10perday
LEFT OUTER JOIN prices AS pnd ON (pnd.symbol = top10perday.symbol AND pnd.date > top10perday.date)
LEFT OUTER JOIN prices AS ptd ON (ptd.symbol = top10perday.symbol AND ptd.date > pnd.date)
GROUP BY top10perday.date, top10perday.symbol
HAVING ((pnd.date = Min(pnd.date) AND ptd.date = Min(ptd.date));
这只是在黑暗中拍摄,但我的理由是:列出你想要的所有股票(top10perday
),并为每只股票获得价格(如果存在),在其日期之后的最小日期填充PriceNextDay以及PriceNextDay填充PriceTwoDays后的最小日期价格。表现可能很糟糕。但测试它,看它是否有效。稍后我们可以尝试改进它。
** EDIT
**包括Rob Farley的评论。
答案 2 :(得分:1)
这应该只是价格表的三个副本之间的连接。问题是你需要加入到下一个交易日,这是一个稍微棘手的问题,因为它并不总是第二天。所以我们最终会遇到一个更复杂的情况(特别是因为有些日子因节假日而被忽略)。
如果它不是Access,您可以使用row_number()按日期订购价格(每个股票代码使用不同的顺序)。
WITH OrderedPrices AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY symbol ORDER BY date) AS RowNum
FROM Prices
)
SELECT orig.*, next_day.price, two_days.price
FROM OrderedPrices orig
JOIN
OrderedPrices next_day
ON next_day.symbol = orig.symbol AND next_day.RowNum = orig.RowNum + 1
JOIN
OrderedPrices two_days
ON two_days.symbol = orig.symbol AND two_days.RowNum = orig.RowNum + 2
;
但你使用的是Access,所以我认为你没有ROW_NUMBER()。
相反,你可以有一个表格,列出日期,有一个TradingDayNumber ......然后使用它来促进你的加入。
SELECT orig.*, next_day.price, two_days.price
FROM Prices orig
JOIN
TradingDays d0
ON d1.date = orig.date
JOIN
TradingDays d1
ON d1.TradingDayNum = d0.TradingDayNum + 1
JOIN
TradingDays d2
ON d2.TradingDayNum = d0.TradingDayNum + 2
JOIN
Prices next_day
ON next_day.symbol = orig.symbol AND next_day.date = d1.date
JOIN
Prices two_days
ON two_days.symbol = orig.symbol AND two_days.date = d2.date
但显然你需要构建自己的TradingDays表......
罗布
答案 3 :(得分:0)
我不是这次改造的大师,但我可以指出你的想法。尝试在查询中的每个符号的日期列中使用Pivot,从日期到日期。这应该会为您提供一个包含许多列的表格,其中包含您使用日期的名称以及每天的价格。实际上它应该对你在给定时间内拥有的每个股票代码都这样做。
根据你想要绘制的图表,我认为如果你试图绘制股票表现,你会看到VWSP而不仅仅是交易的现货价格会很有趣。