查询 return 连续 X 天的最低值 SUM

Query to return the lowest SUM of values over X consecutive days

我什至不知道怎么说这个!...

我有一个包含两列的 table,价格(双精度)和开始日期(日期)。我需要能够查询 table 和 return X 行数,在这个例子中假设为 3 - 我需要拉回具有连续日期的 3 行,例如2019 年 5 月 7 日、8 日、9 日,具有日期范围内最低的价格总和值。

我在想一个接受 startDateRange、endDateRange、持续时间的函数。

它将 return startDateRange 和 endDateRange 之间的行数(持续时间)和这三行加起来将是该日期范围内任意数量行的最便宜(最低)总和对于连续的日期。

例如,如果我想要从 2019 年 5 月 1 日到 2019 年 5 月 14 日之间最便宜的 3 个日期,突出显示的 3 行将是 returned;

我认为 LEAD() 和 LAG() 可能是一个起点,但我不是一个真正的 SQL 人,所以不确定是否有更好的解决方法。

我目前已经在我的业务层上开发了一些 c# 来执行此操作,但是在大型数据集上它有点迟钝 - 直接从我的数据层获取记录列表会很好。

如有任何想法,我们将不胜感激!

提前致谢。

这是您的解决方案,当您开始声明日期时,逻辑就开始了。祝一切顺利。

--table example
declare @laVieja table (price float,fecha date  )

insert into @laVieja values (632,'20150101')
insert into @laVieja values (649,'20150102')
insert into @laVieja values (632,'20150103')
insert into @laVieja values (607,'20150104')
insert into @laVieja values (598,'20150105')
insert into @laVieja values (624,'20150106')
insert into @laVieja values (641,'20150107')
insert into @laVieja values (598,'20150108')
insert into @laVieja values (556,'20150109')
insert into @laVieja values (480,'20150110')
insert into @laVieja values (510,'20150111')
insert into @laVieja values (541,'20150112')
insert into @laVieja values (634,'20150113')
insert into @laVieja values (634,'20150114')
-- end of setting up table example





--declaring dates
declare @fechaIni date, @fechaEnds date 
set @fechaIni = '20150101'
set @fechaEnds = '20150114'

--assigning order based on price
select * , ROW_NUMBER() over (order by price) as unOrden
into #laVieja
from @laVieja
where fecha between @fechaIni and @fechaEnds 

-- declaring variables for cycle 
declare @iteracion float = 1 ,@iteracionMaxima float, @fechaPrimera date, @fechaSegunda date, @fechaTercera date
select @iteracionMaxima = max(unOrden) from #laVieja


--starting cycle
while(@iteracion <= @iteracionMaxima)
begin

        --assigning dates to variables 
        select @fechaPrimera = fecha from #laVieja where unOrden = @iteracion 
        select @fechaSegunda = fecha from #laVieja where unOrden = @iteracion + 1 
        select @fechaTercera = fecha from #laVieja where unOrden = @iteracion + 2 

        --comparing variables 
        if(@fechaTercera = DATEADD(day,1,@fechaSegunda) and @fechaSegunda = DATEADD(day,1,@fechaPrimera))
        begin 

            select * from #laVieja
            where unOrden in (@iteracion,@iteracion+1,@iteracion+2)

        set @iteracion = @iteracionMaxima
        end 

set @iteracion +=1
end 

您可以使用 window 函数计算 3 天的平均值。然后使用 top 1 来选择具有最低平均值的 3 行的集合:

select  top 1 StartDt
,       AvgPrice
from    (
        select  StartDt
        ,       avg(Price) over (order by StartDt rows between 2 preceding 
                                 and current row) AvgPrice
        ,       count(*) over (order by StartDt rows between 2 preceding
                               and current row) RowCnt
        from    prices
        ) sets_of_3_days
where   RowCnt = 3  -- ignore first two rows
order by
        AvgPrice desc

您可以使用带有 OVER (... ROWS BETWEEN) 子句的 window 函数来计算特定行数的 sum/average。然后,您可以使用 ROW_NUMBER 查找其他两行。

WITH cte1 AS (
    SELECT *
         , SUM(Price) OVER (ORDER BY Date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS wsum
         , ROW_NUMBER() OVER (ORDER BY Date) AS rn
    FROM #t
), cte2 AS (
    SELECT TOP 1 rn
    FROM cte1
    WHERE rn > 2
    ORDER BY wsum, Date
)
SELECT *
FROM cte1
WHERE rn BEtWEEN (SELECT rn FROM cte2) - 2 AND (SELECT rn FROM cte2)

在上面的查询中,将 2 替换为 window - 1.

的大小