SQL - 如何对15行的组进行求和并找到最大总和

时间:2018-03-28 18:11:39

标签: tsql query-optimization sql-server-2016

这个问题的目的是通过使用基于集合的操作与迭代(循环,如下所示)优化一些SQL:

一些解释 -

我有一个插入临时表#dataForPeak的cte。每行代表一分钟,并检索相应的值。

对于每一行,我的代码使用while循环一次添加15行(当前行+接下来的14行)。这些总和被插入到另一个临时表#PeakDemandIntervals中,这是我的解决方法,然后找到这些组的最大总数为15

加粗我的最终目标。我的代码实现了这一点,但在26k行的大约12秒内完成。我会查看更多数据,所以我知道这对我的用例来说还不够。

我的问题是,

  • 任何人都可以帮我找到这个循环的快速替代品吗?

它可以包含更多表,CTE,嵌套查询等等。 while循环可能不是问题,它可能是内部代码。

insert into #dataForPeak
    select timestamp, value
    from cte
    order by timestamp;

while @@ROWCOUNT<>0
begin
    declare @timestamp datetime = (select top 1 timestamp from #dataForPeak);
    insert into #PeakDemandIntervals
        select @timestamp, sum(interval.value) as peak
        from (select * from #dataForPeak base
              where base.timestamp >= @timestamp
              and base.timestamp < DATEADD(minute,14,@timestamp)
        ) interval;
    delete from #dataForPeak where timestamp = @timestamp;
end

select max(peak)
from #PeakDemandIntervals;

修改

以下是我的目标示例,使用3分钟而不是15分钟的组。 鉴于数据:

Time | Value
1:50 | 2
1:51 | 4
1:52 | 6
1:53 | 8
1:54 | 6
1:55 | 4
1:56 | 2

我要找的最大总和(峰值)是20,因为该组

1:52 | 6
1:53 | 8
1:54 | 6

总和最高。

如果我需要澄清的话,请告诉我。

1 个答案:

答案 0 :(得分:4)

基于给出的示例,您似乎正在尝试获得滚动总和的最大值。您可以非常轻松地计算15分钟的滚动总和,如下所示:

SELECT   [Time]
        ,[Value] 
        ,SUM([Value]) OVER (ORDER BY [Time] ASC ROWS 14 PRECEDING) [RollingSum]
FROM    #dataForPeak

请注意,此处的关键是ROWS 14 PRECEDING语句。它有效地说明SQL Server应该将前面的14条记录与当前记录相加,这将给你15分钟的间隔。 现在您可以简单地最大化滚动总和的结果。完整查询将如下所示:

;WITH CTE_RollingSum
AS
(
    SELECT   [Time]
            ,[Value] 
            ,SUM([Value]) OVER (ORDER BY [Time] ASC ROWS 14 PRECEDING) [RollingSum]
    FROM    #dataForPeak
)
SELECT  MAX([RollingSum]) AS Peak
FROM    CTE_RollingSum