Sql 查询以返回连续X天内的最小值之和

Sql 查询以返回连续X天内的最小值之和,sql,sql-server,window-functions,Sql,Sql Server,Window Functions,我甚至不知道这个词怎么说 我有一张有两列的表,价格双精度和起始日期。我需要能够查询该表并返回X行数,比如本例中的3行-我需要调回具有连续日期的3行,例如2019年5月7日、8日和9日,它们具有某个日期范围内的最低总价 我在考虑一个函数,它接受startDateRange、endDateRange和duration 它将返回StartDaterRange和endDateRange之间的行数duration,这三行的总和将是该日期范围内连续日期的所有行中最便宜的总和 例如,如果我想要2019年5月1

我甚至不知道这个词怎么说

我有一张有两列的表,价格双精度和起始日期。我需要能够查询该表并返回X行数,比如本例中的3行-我需要调回具有连续日期的3行,例如2019年5月7日、8日和9日,它们具有某个日期范围内的最低总价

我在考虑一个函数,它接受startDateRange、endDateRange和duration

它将返回StartDaterRange和endDateRange之间的行数duration,这三行的总和将是该日期范围内连续日期的所有行中最便宜的总和

例如,如果我想要2019年5月1日至2019年5月14日之间最便宜的3个日期,则将返回突出显示的3行

我认为超前和滞后可能是一个起点,但我不是一个真正的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 

您可以使用窗口函数计算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

您可以将窗口函数与超过。。。ROWS BETWEEN子句计算特定行数的总和/平均值。然后,您可以使用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替换为窗口-1的大小。

如何计算最便宜?平均连续三行?我现在在SQL Server Management Studio 2014上@jarlh.andomar几乎破解了我对他的查询@salman-a的要求,只是想在我的dbms中更好地理解查询,将其分解为3行,谢谢,是的,我认为我的解释令人困惑!它需要有连续的天数,这将给我3个最便宜的天数,但它们不一定是连续的,例如第11天、第12天、第13天。Cheeshi jezorama,您所需要做的就是通过指定开始日期和结束日期来设置代码的限制。如果日期是连续的,查询应该返回3个最低值。太好了,谢谢,这正是我想要的-看起来比@andomar的解决方案要复杂一点-我现在就给它一个爆炸。我也用我的SQL学习了一些西班牙语:Dhaha这是代码的副作用,也是:很高兴它能达到目的。选择前1行StartDt,选择StartDt中的AvgPrice,选择StartDt中的sumPrice超过order by StartDt行在前2行和当前行AvgPrice之间,从laVieja2集合中的2个前一行和当前行RowCnt(共3天,其中RowCnt=3)之间按StartDt排序的count1-按AVGPRICEOOOH忽略前两行排序!这正是我所追求的,非常感谢——我用avgPrice换成了sumPrice——这让我创造了一张总共X天的记录。但有一个障碍,它带来了连续3天最便宜的总价格的一排。。。i、 e.2019年5月12日:1531英镑,总计480510541-有没有办法从我的屏幕截图中分别抽出第10、11、12行的三行?再次感谢!从未使用过前面的命令或类似命令!该解决方案不考虑只有连续行时,日期是否是连续的。证据将第10天的日期更新为第9天,并运行此过程rephwaaarrr。叙事诗我做了一些基于日期和价格的可怕的IN子句,以从汇总行中获得我想要的3行的列表,但很明显,我应该远离SQL,因为这就是您要做的!非常感谢你!是否有一种方法可以使此部分中的数值动态变化:在前面2行之间按日期排序,即数字“2”?我似乎不能用一个变量来代替2的值。再次感谢。看起来我必须通过四处查看来动态构建SQL:您可以使用相关子查询,或者交叉应用。但那将是糟糕的表现。看到了吗