2013-04-25 3 views
0

У меня есть запрос, который группирует агрегированные суммы по месяцам.SQL Server: как группировать значения по интервалу месяца со смещением

Это запрос:

Declare @IsByStatus bit 
Set @IsByStatus = 0 

SELECT 
    CAST((DATEDIFF(month, '2012-01-01T06:00:00', datTimeStamp)) AS int) AS [Index] , 
    Min(datTimeStamp) as [From], 
    Max(datTimeStamp) as [To], 
    Sum(CASE CAST(intIO_ID AS nvarchar(100)) 
      WHEN N'284' THEN Value ELSE NULL END) AS [286] 
FROM 
    [IOValuesFn](@IsByStatus) IOValues 
WHERE 
    datTimeStamp >= '2012-01-01T06:00:00' 
    AND datTimeStamp < '2013-01-01T05:59:59' 
    AND intIO_ID IN (284) 
GROUP BY 
    CAST ((DATEDIFF(Month,'2012-01-01T06:00:00', datTimeStamp)) AS int) 
ORDER BY 
    [From] 

И это результат:

Index From To 286 
0 2012-01-07 07:00:00.000 2012-01-31 23:00:00.000 142579.898864746 
1 2012-02-01 00:00:00.000 2012-02-29 23:00:00.000 139486.498001099 
2 2012-03-01 00:00:00.000 2012-03-31 23:00:00.000 99516.3022232056 
3 2012-04-01 00:00:00.000 2012-04-30 23:00:00.000 84597.599899292 
4 2012-05-01 00:00:00.000 2012-05-31 23:00:00.000 67085.2983112335 
5 2012-06-01 00:00:00.000 2012-06-30 23:00:00.000 67768.9982643127 
6 2012-07-01 00:00:00.000 2012-07-31 23:00:00.000 121100.264842987 
7 2012-08-01 00:00:00.000 2012-08-31 23:00:00.000 165768.90776825 
8 2012-09-01 00:00:00.000 2012-09-30 23:00:00.000 97441.7333068848 
9 2012-10-01 00:00:00.000 2012-10-31 23:00:00.000 153764.736312866 
10 2012-11-01 00:00:00.000 2012-11-30 23:00:00.000 153601.413961411 
11 2012-12-01 00:00:00.000 2012-12-31 23:00:00.000 142521.07028389 
12 2013-01-01 00:00:00.000 2013-01-01 05:00:00.000 1192.32000732422 

Теперь я хочу сделать подобную логику, которая будет также вставить смещение в месяц начала и окончания время.

например. первый период начнется 1 января 11:00 и завершится 1 февраля 10:59:59.

То же самое касается каждого последующего месяца.

Заранее спасибо за вашу помощь, Омер

ответ

3

Посмотрите на примере ниже. Хитрость заключается в том, чтобы добавить отрицательную величину смещения, так что за час до 11:00 в первый день месяца «толкается» в предыдущий месяц. Настройка

Схема:

create function iovaluesfn(@isbystatus bit) returns table as return 
select datTimeStamp = '20130101 10:50', intIO_ID = 284, Value = 1 union all 
select '20130101 11:00', 284, 1 union all 
select '20130102 11:00', 284, 2 union all 
select '20130301 11:00', 284, 3 union all 
select '20130401 11:00', 284, 4 union all 
select '20120501 11:00', 284, 5 union all 
select '20120601 11:00', 284, 6 union all 
select '20120101 11:00', 284, 7 union all 
select '20120102 11:00', 284, 8 union all 
select '20120101 11:01', 284, 9 union all 
select '20120101 10:59', 284,10 union all -- ** this value is counted in Dec 2011 
select '20120101 11:00', 284,11 union all 
select '20120101 11:01', 281,12 union all 
select '20120101 10:59', 281,13 union all 
select '20120101 11:00', 281,14 
GO 

Запрос:

Declare @IsByStatus bit; 
Set @IsByStatus = 0; 

;with IOValues as (
    select DATEADD(hour, -11, datTimeStamp) datTimeStamp, intIO_ID, Value 
    FROM [IOValuesFn](@IsByStatus) 
    WHERE datTimeStamp >= '2012-01-01T06:00:00' AND datTimeStamp < '2013-01-01T05:59:59' 
    AND intIO_ID IN (284) 
) 
    SELECT CAST((DATEDIFF(month,'2012-01-01T06:00:00',datTimeStamp)) AS int) AS [Index], 
     Min(datTimeStamp) as [From], 
     Max(datTimeStamp) as [To], 
     Sum(CASE CAST(intIO_ID AS nvarchar(100)) 
      WHEN N'284' THEN Value ELSE NULL END) AS [286] 
    FROM IOValues 
GROUP BY CAST ((DATEDIFF(Month,'2012-01-01T06:00:00',datTimeStamp))AS int) 
order by [From]; 

Результаты:

| INDEX |    FROM |    TO | 286 | 
---------------------------------------------------------- 
| -1 | December, 31 2011 | December, 31 2011 | 10*** | 
|  0 | January, 01 2012 | January, 02 2012 | 35 | 
|  4 |  May, 01 2012 |  May, 01 2012 | 5 | 
|  5 |  June, 01 2012 |  June, 01 2012 | 6 | 

SQL Fiddle Demo

+0

Большое спасибо, я дам ему попробовать :) –

Смежные вопросы