Pergunta

Eu gostaria de tirar a média da diferença de horário da Tabela 1 abaixo. Os valores não são consecutivos e, ocasionalmente, o valor do tempo é repetido; portanto, preciso 1) classificar por tempo, 2) descartar valores não únicos, 3) executar a diferença de tempo (em milissegundos); em seguida, 4) em média a diferença de tempo resultante valores. Além disso, gostaria de 5) limitar a operação datediff a um intervalo de tempo escolhido, como onde _timestamp> = '20091220 11: 59: 56.1' e _timestamp <= _timestamp> = '20091220 11: 59: 56.8'. Estou muito perplexo como juntar tudo isso!

Tabela 1:
_Timestamp
2009-12-20 11:59:56.0
2009-12-20 11:59:56.5
2009-12-20 11:59:56.3
2009-12-20 11:59:56.4
2009-12-20 11:59:56.4
2009-12-20 11:59:56.9

Foi útil?

Solução

Aqui está um que funciona e não é feio:

;WITH Time_CTE AS
(
    SELECT
        MIN(_Timestamp) AS dt,
        ROW_NUMBER() OVER (ORDER BY MIN(_Timestamp)) AS RowNum
    FROM Table1
    GROUP BY _Timestamp
)
SELECT
    t1.dt AS StartDate,
    t2.dt AS EndDate,
    DATEDIFF(MS, t1.dt, t2.dt) AS Elapsed
FROM Time_CTE t1
INNER JOIN Time_CTE t2
ON t2.RowNum = t1.RowNum + 1

Dará a você a seguinte saída do seu exemplo:

StartDate               | EndDate                 | Elapsed
------------------------+-------------------------+--------
2009-12-20 11:59:56.000 | 2009-12-20 11:59:56.300 | 300
2009-12-20 11:59:56.300 | 2009-12-20 11:59:56.400 | 100
2009-12-20 11:59:56.400 | 2009-12-20 11:59:56.500 | 100
2009-12-20 11:59:56.500 | 2009-12-20 11:59:56.900 | 400

Editar: se você deseja restringir as faixas de tempo, basta adicionar WHERE _Timestamp BETWEEN @StartDate AND @EndDate antes de o GROUP BY linha.

Edit2: e se você quiser a média, mude essa final SELECT t1.dt, ... declaração para:

SELECT AVG(DATEDIFF(MS, t1.dt, t2.dt))
FROM Time_CTE t1 ... (same as above)

Outras dicas

A etapa 1 é selecionar apenas horários únicos:

SELECT DISTINCT _TimeStamp FROM table 
    WHERE _TimeStamp >= '20091220 11:59:56.1' AND _TimeStamp <= '20091220 11:59:56.8';

Então, se você quiser, digamos, compare todos os momentos um com o outro (não tenho certeza de como você deseja selecionar horários), você pode fazer algo louco como:

SELECT t1._TimeStamp, t2._TimeStamp, DATEDIFF(ms,t1._TimeStamp,t2._TimeStamp) FROM 
    (SELECT DISTINCT _TimeStamp FROM table 
        WHERE _TimeStamp >= '20091220 11:59:56.1' AND _TimeStamp <= '20091220 11:59:56.8') AS t1 
    INNER JOIN
    (SELECT DISTINCT _TimeStamp FROM table 
        WHERE _TimeStamp >= '20091220 11:59:56.1' AND _TimeStamp <= '20091220 11:59:56.8') AS t2
WHERE t1._TimeStamp != t2._TimeStamp;

Minha sintaxe pode estar desligada, porque estou vindo do MySQL, mas algo semelhante deve funcionar.

Se você quiser a média, tente tomar a média dos resultados acima:

SELECT AVG(DATEDIFF(ms,t1._TimeStamp,t2._TimeStamp)) FROM 
    (SELECT DISTINCT _TimeStamp FROM table 
        WHERE _TimeStamp >= '20091220 11:59:56.1' AND _TimeStamp <= '20091220 11:59:56.8') AS t1 
    INNER JOIN
    (SELECT DISTINCT _TimeStamp FROM table 
        WHERE _TimeStamp >= '20091220 11:59:56.1' AND _TimeStamp <= '20091220 11:59:56.8') AS t2
WHERE t1._TimeStamp != t2._TimeStamp;

Ainda não testado, mas em teoria, acho que deveria funcionar.

Se minhas suposições sobre o que você deseja estão corretas, vejo duas maneiras de fazê -lo.

A maneira direta:

SELECT
    AVG(DATEDIFF(ms, T1.my_time, T2.my_time))
FROM
    My_Table T1
INNER JOIN My_Table T2 ON
    T2.my_time > T1.my_time
WHERE
    NOT EXISTS
    (
        SELECT
            *
        FROM
            My_Table T3
        WHERE
            (T3.my_time > T1.my_time AND T3.my_time < T2.my_time) OR
            (T3.my_time = T1.my_time AND T3.my_pk < T1.my_pk) OR
            (T3.my_time = T2.my_time AND T3.my_pk < T2.my_pk)
    )

A maneira complicada:

SELECT
    DATEDIFF(ms, MIN(my_time), MAX(my_time))/(COUNT(DISTINCT my_time) - 1)
FROM
    My_Table

Afinal, as diferenças médias são apenas a diferença total dividida pelo número de divisões nas quais você está dividindo.

Você precisará adicionar onde as cláusulas para o intervalo de dados se desejar limitar isso e precisará explicar a possibilidade de dividir por zero na segunda consulta.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top