滚动值的复最小值
Posted
技术标签:
【中文标题】滚动值的复最小值【英文标题】:Complex Minimum of Rolling Values 【发布时间】:2020-02-18 19:45:18 【问题描述】:我正在研究一个复杂的统计函数,该函数需要找到至少 10 个先前的计算值。先前每一行的计算值不仅取决于当前行的平均值,还取决于先前行的计算。下图显示了所需的查询结果:
我能够获得 10 天的平均值,但是对于如何在不使用窗口函数的情况下应用其他计算的方法非常低效,我感到很困惑。以下是我到目前为止的代码:
CREATE TABLE #TBL(
[id] int IDENTITY(1,1) NOT NULL,
[price] numeric(20,10)
)
INSERT INTO #TBL ([price])
VALUES (93.02),(90.56),(88.63),(90.3),(91.58),(90.42),(89.5),(89.23),(87.07),(85.88),(86.04),(87.26),(87.67),(84.37),(84.13),(83.3),(82.4),(81.73),(82),(80.69),(82.13)
SELECT
[id], [price],
CASE WHEN [id] >= 10 THEN
avg([price]) OVER(ORDER BY ID ASC ROWS BETWEEN 9 PRECEDING AND CURRENT ROW)
END AS [average (last 10)]
FROM #TBL
任何有关创建高效查询的帮助将不胜感激。
【问题讨论】:
【参考方案1】:CREATE TABLE #TBL(
[id] int IDENTITY(1,1) NOT NULL primary key clustered, --!!!!
[price] numeric(20,10)
)
INSERT INTO #TBL ([price])
VALUES (93.02),(90.56),(88.63),(90.3),(91.58),(90.42),(89.5),(89.23),(87.07),(85.88),(86.04),(87.26),(87.67),(84.37),(84.13),(83.3),(82.4),(81.73),(82),(80.69),(82.13)
select *
from
(
select *, avg([price]) OVER(ORDER BY ID ASC ROWS BETWEEN 9 PRECEDING AND CURRENT ROW) as avg10
from #TBL
) as a
outer apply
(
select min(r.runningdiff) as mindiff
from
(
select sum(l10.diff) over (order by l10.id) as runningdiff
from
(
select TOP (10) b.id, a.avg10 - b.price as diff
from #Tbl as b
where 1=1
and a.Id >= 10
and b.Id between a.id-9 and a.Id
) as l10
) as r
) as rt
【讨论】:
以上是关于滚动值的复最小值的主要内容,如果未能解决你的问题,请参考以下文章