在这种情况下,我将有一个表,其中包含“水果”列,该列中将包含大约 1000 多个不同的条目,每天一个条目。我想做的是,对于每种不同类型的水果,我想找到当天销售的水果数量是前两天水果总和的 2 倍。
例如,如果在第 1 天和第 2 天,每天售出 1 个苹果,那么我总共售出 2 个苹果,我想知道第二天的销量是前一天的 2 倍,所以如果第 3 天售出了 4 个苹果,那么这是一个正结果,但是如果售出了 3 个,那么这将是一个负结果。我组装了一个非常笨重且缓慢的光标,我对结果没有信心。需要考虑的事情之一是数据始终需要按日期降序排序,有时数据不是每天都会填充,ID 会乱序。
这是一个测试查询,其中包含我正在寻找的最终结果。
declare @testTable table(Id int not null identity(1,1),Fruit nvarchar(10),Sold int, DateSold date)
DECLARE @StartDate datetime = '2024-01-22';
DECLARE @EndDate datetime = Dateadd(day,100,@StartDate);
WITH theDates AS
(SELECT @StartDate as theDate
UNION ALL
SELECT DATEADD(day, 1, theDate)
FROM theDates
WHERE DATEADD(day, 1, theDate) <= @EndDate
)
insert into @testTable(Fruit,Sold,DateSold)
SELECT 'Apple',90+ROW_NUMBER() OVER(ORDER BY theDate),theDate as theValue
FROM theDates
union
SELECT 'Orange',90+ROW_NUMBER() OVER(ORDER BY theDate),theDate as theValue
FROM theDates
union
SELECT 'Pears',90+ROW_NUMBER() OVER(ORDER BY theDate),theDate as theValue
FROM theDates
union
SELECT 'Plums',90+ROW_NUMBER() OVER(ORDER BY theDate),theDate as theValue
FROM theDates
OPTION (MAXRECURSION 0)
摆弄样本数据:
declare @appleRow int = (SELECT TOP 1 Id FROM @testTable where fruit = 'Apple' ORDER BY NEWID());
declare @ornageRow int = (SELECT TOP 1 Id FROM @testTable where fruit = 'Orange' ORDER BY NEWID());
declare @pearRow int = (SELECT TOP 1 Id FROM @testTable where fruit = 'Pears' ORDER BY NEWID());
declare @plumRow int = (SELECT TOP 1 Id FROM @testTable where fruit = 'Plums' ORDER BY NEWID());
update @testTable
set Sold = Sold + 250
where Id in (@appleRow,@ornageRow,@pearRow,@plumRow);
select * from @testTable;
--these are the ids am looking for
select * from @testTable
where Id in (@appleRow,@ornageRow,@pearRow,@plumRow);
我会使用移动窗口技术。扩展你原来的小提琴:
select sq.*
from (
select t.*,
isnull(sum(t.Sold) over(
partition by t.Fruit
order by t.DateSold
-- Moving window: 2 rows before the current
rows between 2 preceding and 1 preceding
), 0) as [Prev2DaysSale]
from testTable t
) sq
where sq.Sold > 2 * sq.Prev2DaysSale
order by sq.Fruit, sq.DateSold;
LAG()
窗口函数。
试试这个:
WITH lags AS (
select Fruit, DateSold, Sold
,Lag(Sold, 1, 0) OVER (PARTITION BY Fruit ORDER BY DateSold DESC) YesterdaySold
,Lag(Sold, 2, 0) OVER (PARTITION BY Fruit ORDER BY DateSold DESC) DayBeforeSold
from TestTable
)
SELECT *
FROM lags
WHERE Sold > 2 * (YesterdaySold + DayBeforeSold);
在这里查看: