滚动值的复最小值

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

【讨论】:

以上是关于滚动值的复最小值的主要内容,如果未能解决你的问题,请参考以下文章

Python:从字典中获取具有最小值但有多个最小值的键

R:每列最小值的行号

sql查询时间最小值的列

浏览器滚动条卷去的高度

找出一组数组中最大值最大值的角标最小值最小值的角标及平均数

Matlab中已知函数值的最小值求对应的自变量值...