Sql 排除前一交易日平均值计算中的空或零
我以为我得到了,但实际上没有。处理一些交易数据,只需要计算交易日的平均股价。使用以下查询获得3天平均值;但最近发现,在交易假日可以分红;因此,在事实表中有股票代码的数据,closeprice要么为零,要么为空 请帮助我改进我的查询,以忽略前3个交易日平均计算中的零和零Sql 排除前一交易日平均值计算中的空或零,sql,sql-server,azure-sql-database,Sql,Sql Server,Azure Sql Database,我以为我得到了,但实际上没有。处理一些交易数据,只需要计算交易日的平均股价。使用以下查询获得3天平均值;但最近发现,在交易假日可以分红;因此,在事实表中有股票代码的数据,closeprice要么为零,要么为空 请帮助我改进我的查询,以忽略前3个交易日平均计算中的零和零 select StockCode, datekey, ClosePrice, AVG(ClosePrice) OVER (partition by StockCode order by datekey ROWS BETWEEN
select StockCode, datekey, ClosePrice,
AVG(ClosePrice) OVER (partition by StockCode order by datekey
ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING) Avg3Days
from Fact
假设您有一个指示交易日的标志,您可以这样做:
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
,则它将不会包含在平均值中。如果唯一的指标是收盘价
,则一种方法是:
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'
来过滤无效的股票代码。您可以通过StockCode
和符号(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
返回
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
如何在数据中区分交易日和非交易日?样本数据和期望的结果会有所帮助。你是在寻找日权重吗?当你说“忽略”时,你的意思是如果“第2天”是
NULL
,那么你想要(第1天+第3天)/2
,还是以(第1天+第3天+第4天)/3
结束?这太棒了!!感谢您提供这段代码。我接受这个解决方案。2019-06-15到2019-06-19之间的平均价格是否有办法显示为NULL或0,因为在我们得到3个实际值之前,它是不正确的。在我的真实案例中,我得到了30天、45天和60天的平均值。所以,基本上,前3个月(包括假期)的平均值是错误的。@ITNube很高兴这有帮助。看一眼UPDTE