这个问题的目的是通过使用基于集合的操作与迭代(循环,如下所示)优化一些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
总和最高。
如果我需要澄清的话,请告诉我。
答案 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