Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Agrupe DateTime em intervalos de 5,15,30 e 60 minutos


Usando
datediff(minute, '1990-01-01T00:00:00', yourDatetime)

lhe dará o número de minutos desde 1990-1-1 (você pode usar a data base desejada).

Então você pode dividir por 5, 15, 30 ou 60, e agrupar pelo resultado dessa divisão. Verifiquei que será avaliada como uma divisão inteira, então você obterá um número inteiro que você pode usar para agrupar.

ou seja
group by datediff(minute, '1990-01-01T00:00:00', yourDatetime) /5

ATUALIZAÇÃO Como a pergunta original foi editada para exigir que os dados sejam mostrados no formato de data e hora após o agrupamento, adicionei esta consulta simples que fará o que o OP deseja:
-- This convert the period to date-time format
SELECT 
    -- note the 5, the "minute", and the starting point to convert the 
    -- period back to original time
    DATEADD(minute, AP.FiveMinutesPeriod * 5, '2010-01-01T00:00:00') AS Period,
    AP.AvgValue
FROM
    -- this groups by the period and gets the average
    (SELECT
        P.FiveMinutesPeriod,
        AVG(P.Value) AS AvgValue
    FROM
        -- This calculates the period (five minutes in this instance)
        (SELECT 
            -- note the division by 5 and the "minute" to build the 5 minute periods
            -- the '2010-01-01T00:00:00' is the starting point for the periods
            datediff(minute, '2010-01-01T00:00:00', T.Time)/5 AS FiveMinutesPeriod,
            T.Value
        FROM Test T) AS P
    GROUP BY P.FiveMinutesPeriod) AP

NOTA:Eu dividi isso em 3 subconsultas para maior clareza. Você deve lê-lo de dentro para fora. Obviamente, poderia ser escrito como uma consulta única e compacta

OBSERVAÇÃO:se você alterar o período e a data e hora de início, poderá obter qualquer intervalo necessário, como semanas a partir de um determinado dia ou o que precisar

Se você quiser gerar dados de teste para esta consulta, use isto:
CREATE TABLE Test
( Id INT IDENTITY PRIMARY KEY,
Time DATETIME,
Value FLOAT)

INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:00:22', 10)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:03:22', 10)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:04:45', 10)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:07:21', 20)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:10:25', 30)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:11:22', 30)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:14:47', 30)

O resultado da execução da consulta é este:
Period                     AvgValue
2012-03-22 00:00:00.000    10
2012-03-22 00:05:00.000    20
2012-03-22 00:10:00.000    30