Запрос возврата минимальной суммы значений за X дней подряд - PullRequest
0 голосов
/ 07 февраля 2019

Я даже не знаю, как произнести это слово! ...

У меня есть таблица с двумя столбцами: Price (double) и StartDate (Date).Мне нужно иметь возможность запросить таблицу и вернуть количество строк X, скажем, 3 для этого примера - мне нужно извлечь 3 строки с последовательными датами, например, 7, 8, 9 мая 2019 года с самой низкой суммой.d ценовые значения из диапазона дат.

Я думаю, что функция, которая принимает startDateRange, endDateRange, duration.

Она будет возвращать количество строк (длительность) между startDateRange и endDateRange и эти три строки, когда сумма будетбудет самой дешевой (самой низкой) суммой любого числа строк в этом диапазоне дат для последовательных дат.

Так, например, если бы я хотел получить самые дешевые 3 даты в период с 1 мая 2019 года по 14 мая 2019 года,будут выделены 3 выделенные строки;

enter image description here

Я думаю, что, возможно, LEAD () и LAG () могут быть отправной точкой, но я не совсемSQL человек, так что не уверен, есть ли лучший способ обойти это.

Я разработал некоторые c # на своем бизнес-уровне, чтобы сделать это в настоящее время, но для больших наборов данных это немного вяло - было бы неплохо получить список записей прямо из моего уровня данных.

Любые идеи будут с благодарностью!

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 07 февраля 2019

Вы можете рассчитать средние значения за 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
0 голосов
/ 07 февраля 2019

Вы можете использовать оконные функции с предложением OVER (... 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 .

0 голосов
/ 07 февраля 2019

Вот ваше решение, логика начинается, когда вы начинаете объявлять даты.Всего наилучшего.

--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 
...