我以为我知道了,但实际上没有。处理一些交易数据,仅需要计算交易日的平均股价。将以下查询用于3天平均值;但最近发现交易假期中可能会有股息;因此,在事实表中的那几天,都有股票代码的数据,并且收盘价为零或为空。
请帮助我改进查询,以忽略前三个交易日平均计算中的零和空值
select StockCode, datekey, ClosePrice,
AVG(ClosePrice) OVER (partition by StockCode order by datekey
ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING) Avg3Days
from Fact
答案 0 :(得分:1)
假设您有一个指示交易日的标记,则可以执行以下操作:
SELECT StockCode, datekey, ClosePrice,
(CASE WHEN isTradingDay = 1
THEN AVG(ClosePrice) OVER (PARTITION BY StockCode, isTradingDay
ORDER BY datekey
ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING
)
END) as Avg3Days
FROM Fact;
这需要前三个交易日的平均值。非交易日的值为NULL
。
如果StockCode
是NULL
,则无论如何都不会将其包括在平均值中。如果唯一的指标是closePrice
,则一种方法是:
SELECT f.StockCode, f.datekey, f.ClosePrice,
(CASE WHEN v.isTradingDay = 1
THEN AVG(f.ClosePrice) OVER (PARTITION BY f.StockCode, v.isTradingDay
ORDER BY f.datekey
ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING
)
END) as Avg3Days
FROM Fact f CROSS APPLY
(VALUES (CASE WHEN f.ClosePrice > 0 THEN 1 ELSE 0 END)
) v(isTradingDay);
就个人而言,我希望有一个明确的交易日指标,而不是依靠收盘价的特殊值。例如,由于某些公司特定原因,一只股票的交易可能会暂停。
您可能还需要WHERE f.StockCode <> ''
来过滤掉无效的股票代码。
答案 1 :(得分:1)
您可以按StockCode
和sign(NullIf([ClosePrice],0))
进行分区,而不必知道交易日。
示例
Declare @YourTable Table ([datekey] date,[StockCode] varchar(50),[ClosePrice] money)
Insert Into @YourTable Values
('2019-06-15','xyx',5)
,('2019-06-16','xyx',10)
,('2019-06-17','xyx',NULL)
,('2019-06-18','xyx',0)
,('2019-06-19','xyx',15)
,('2019-06-20','xyx',20)
Select *
,AvgPrice = AVG(ClosePrice) over (partition by StockCode,sign(NullIf([ClosePrice],0)) order By datekey rows between 3 preceding and 1 preceding )
from @YourTable
Order By datekey
返回
datekey StockCode ClosePrice AvgPrice
2019-06-15 xyx 5.00 NULL
2019-06-16 xyx 10.00 5.00
2019-06-17 xyx NULL NULL
2019-06-18 xyx 0.00 NULL
2019-06-19 xyx 15.00 7.50
2019-06-20 xyx 20.00 10.00
更新
有点难看,但也许是这样的
Select *
,AvgPrice = case when sum(1) over (partition by StockCode,sign(NullIf([ClosePrice],0)) order By datekey rows between 3 preceding and 1 preceding ) = 3
then avg(ClosePrice) over (partition by StockCode,sign(NullIf([ClosePrice],0)) order By datekey rows between 3 preceding and 1 preceding )
else null end
from @YourTable
Order By datekey
返回