代码之家  ›  专栏  ›  技术社区  ›  Camilo

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

  •  0
  • Camilo  · 技术社区  · 6 年前

    这个问题的目的是通过使用基于集的操作与迭代(循环,就像我下面所做的那样)来优化一些SQL:

    一些解释-

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

    对于每一行,我的代码都使用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 回复  |  直到 6 年前
        1
  •  4
  •   Edmond Quinton    6 年前

    根据给出的示例,您似乎正在尝试获得滚动和的最大值。您可以很容易地计算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