查找行值比前两行组合大 X2 的所有行的最有效方法

问题描述 投票:0回答:1

在这种情况下,我将有一个表,其中包含“水果”列,该列中将包含大约 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)

摆弄样本数据:

https://dbfiddle.uk/coq20xzk

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);
sql sql-server
1个回答
1
投票

这里的关键是

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);

在这里查看:

https://dbfiddle.uk/h5vzZJPB

© www.soinside.com 2019 - 2024. All rights reserved.