Я нашел способ повысить производительность, выполняя запрос за один раз, а не итерируя все временные точки.Сначала мин / макс для каждой точки и сохраните их во временной таблице.
CREATE TABLE #ProfiledData(ID int identity(1,1), TimePoint nchar(5), MinValue float NULL, MaxValue float NULL, RangeWidth float NULL)
DECLARE @RangeCount float
SET @RangeCount = 9
declare @tData table(DeviceID nvarchar(10), FooTime datetime, Value float)
--just dummy data, actual data will have full 96 points for each day
INSERT INTO @tData VALUES ('PM00100', '2010-01-01 00:00', 3)
INSERT INTO @tData VALUES ('PM00100', '2010-01-02 00:00', 4)
INSERT INTO @tData VALUES ('PM00100', '2010-01-03 00:00', 5)
INSERT INTO @tData VALUES ('PM00100', '2010-01-04 00:00', 2)
INSERT INTO @tData VALUES ('PM00100', '2010-01-05 00:00', 3)
INSERT INTO @tData VALUES ('PM00100', '2010-01-06 00:00', 4)
INSERT INTO @tData VALUES ('PM00100', '2010-01-07 00:00', 5)
INSERT INTO @tData VALUES ('PM00100', '2010-01-08 00:00', 6)
INSERT INTO @tData VALUES ('PM00100', '2010-01-09 00:00', 7)
INSERT INTO @tData VALUES ('PM00100', '2010-01-10 00:00', 11)
INSERT INTO @tData VALUES ('PM00100', '2010-01-11 00:00', 12)
INSERT INTO @tData VALUES ('PM00100', '2010-01-12 00:00', 13)
INSERT INTO @tData VALUES ('PM00100', '2010-01-13 00:00', 14)
INSERT INTO @tData VALUES ('PM00100', '2010-01-14 00:00', 15)
INSERT INTO @tData VALUES ('PM00100', '2010-01-15 00:00', 16)
INSERT INTO @tData VALUES ('PM00100', '2010-01-16 00:00', 17)
INSERT INTO @tData VALUES ('PM00100', '2010-01-17 00:00', 18)
INSERT INTO @tData VALUES ('PM00100', '2010-01-18 00:00', 10)
INSERT INTO @tData VALUES ('PM00100', '2010-01-19 00:00', 19)
INSERT INTO @tData VALUES ('PM00100', '2010-01-20 00:00', 9)
INSERT INTO @tData VALUES ('PM00100', '2010-01-21 00:00', 8)
INSERT INTO @tData VALUES ('PM00100', '2010-01-22 00:00', 3)
INSERT INTO @tData VALUES ('PM00100', '2010-01-23 00:00', 4)
INSERT INTO @tData VALUES ('PM00100', '2010-01-24 00:00', 4)
INSERT INTO @tData VALUES ('PM00100', '2010-01-25 00:00', 2)
INSERT INTO @tData VALUES ('PM00100', '2010-01-26 00:00', 2)
INSERT INTO @tData VALUES ('PM00100', '2010-01-27 00:00', 5)
INSERT INTO @tData VALUES ('PM00100', '2010-01-28 00:00', 6)
INSERT INTO @tData VALUES ('PM00100', '2010-01-29 00:00', 2)
INSERT INTO @tData VALUES ('PM00100', '2010-01-30 00:00', 14)
INSERT INTO @tData VALUES ('PM00100', '2010-01-31 00:00', 15)
INSERT INTO @tData VALUES ('PM00100', '2010-02-01 00:00', 25)
INSERT INTO @tData VALUES ('PM00100', '2010-01-01 00:15', 3)
INSERT INTO @tData VALUES ('PM00100', '2010-01-02 00:15', 4)
INSERT INTO @tData VALUES ('PM00100', '2010-01-03 00:15', 5)
INSERT INTO @tData VALUES ('PM00100', '2010-01-04 00:15', 2)
INSERT INTO @tData VALUES ('PM00100', '2010-01-05 00:15', 3)
INSERT INTO @tData VALUES ('PM00100', '2010-01-06 00:15', 4)
INSERT INTO @tData VALUES ('PM00100', '2010-01-07 00:15', 5)
INSERT INTO @tData VALUES ('PM00100', '2010-01-08 00:15', 6)
INSERT INTO @tData VALUES ('PM00100', '2010-01-09 00:15', 7)
INSERT INTO @tData VALUES ('PM00100', '2010-01-10 00:15', 11)
INSERT INTO @tData VALUES ('PM00100', '2010-01-11 00:15', 12)
INSERT INTO @tData VALUES ('PM00100', '2010-01-12 00:15', 13)
INSERT INTO @tData VALUES ('PM00100', '2010-01-13 00:15', 14)
INSERT INTO @tData VALUES ('PM00100', '2010-01-14 00:15', 15)
INSERT INTO @tData VALUES ('PM00100', '2010-01-15 00:15', 16)
INSERT INTO @tData VALUES ('PM00100', '2010-01-16 00:15', 17)
INSERT INTO @tData VALUES ('PM00100', '2010-01-17 00:15', 18)
INSERT INTO @tData VALUES ('PM00100', '2010-01-18 00:15', 10)
INSERT INTO @tData VALUES ('PM00100', '2010-01-19 00:15', 19)
INSERT INTO @tData VALUES ('PM00100', '2010-01-20 00:15', 9)
INSERT INTO @tData VALUES ('PM00100', '2010-01-21 00:15', 8)
INSERT INTO @tData VALUES ('PM00100', '2010-01-22 00:15', 3)
INSERT INTO @tData VALUES ('PM00100', '2010-01-23 00:15', 4)
INSERT INTO @tData VALUES ('PM00100', '2010-01-24 00:15', 4)
INSERT INTO @tData VALUES ('PM00100', '2010-01-25 00:15', 2)
INSERT INTO @tData VALUES ('PM00100', '2010-01-26 00:15', 2)
INSERT INTO @tData VALUES ('PM00100', '2010-01-27 00:15', 5)
INSERT INTO @tData VALUES ('PM00100', '2010-01-28 00:15', 6)
INSERT INTO @tData VALUES ('PM00100', '2010-01-29 00:15', 2)
INSERT INTO @tData VALUES ('PM00100', '2010-01-30 00:15', 14)
INSERT INTO @tData VALUES ('PM00100', '2010-01-31 00:15', 15)
INSERT INTO @tData VALUES ('PM00100', '2010-02-01 00:15', 25)
INSERT INTO #ProfiledData (TimePoint) VALUES ('00:00')
INSERT INTO #ProfiledData (TimePoint) VALUES ('00:15')
--...
--...
UPDATE #ProfiledData SET MinValue = m.MinValue, MaxValue = m.MaxValue, RangeWidth = (m.MaxValue - m.MinValue) / @RangeCount
FROM (SELECT CONVERT(nchar(5), FooTime, 108) AS TimePoint, MIN(Value) AS MinValue, MAX(Value) AS MaxValue
FROM @tData
GROUP BY CONVERT(nchar(5), FooTime, 108)) m
LEFT JOIN #ProfiledData a ON a.TimePoint = m.TimePoint
SELECT a.TimePoint
,FLOOR((Value - MinValue)/ RangeWidth) * RangeWidth + MinValue as LowerBound
,FLOOR((Value - MinValue)/ RangeWidth) * RangeWidth + RangeWidth + MinValue as UpperBound
,COUNT(*) AS Total
,FLOOR((Value - MinValue)/ RangeWidth) AS Position
FROM @tData d
INNER JOIN #ProfiledData a ON a.TimePoint = CONVERT(nchar(5), d.FooTime, 108)
WHERE d.DeviceID = 'PM00100'
GROUP BY a.TimePoint, RangeWidth, MinValue, FLOOR((Value - MinValue) / RangeWidth)
DROP TABLE #ProfiledData