Question

Je voudrais prendre la moyenne de la différence de temps de Tableau 1 ci-dessous. Les valeurs ne sont pas consécutifs, et de temps en temps la valeur de temps est répété, je doivent 1) trier par le temps, 2) rejeter les valeurs non uniques, 3) effectuer la différence de temps (en millisecondes), puis 4) moyenne de la différence de temps résultant valeurs. De plus, je voudrais 5) limiter l'opération de datediff à un intervalle de temps choisi, comme OÙ _timestamp> = '20091220 11: 59: 56,1' ET _timestamp <= _timestamp> = '20091220 11: 59: 56,8. Je suis assez perplexe comment mettre tout cela ensemble!

Tableau 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

Était-ce utile?

La solution

Voici un qui fonctionne et n'est pas laid:

;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

vous donnera la sortie suivante de votre exemple:

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

Edit:. Si vous voulez limiter les plages de temps puis ajoutez juste WHERE _Timestamp BETWEEN @StartDate AND @EndDate avant la ligne de GROUP BY

Edit2: Et si vous voulez que la moyenne, puis modifiez cette instruction SELECT t1.dt, ... final:

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

Autres conseils

Étape 1 est de ne sélectionner que les temps uniques:

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

Alors, si vous voulez, par exemple, de comparer tout le temps les uns avec les autres (ne savez pas comment vous voulez sélectionner les temps), vous pouvez faire quelque chose de fou comme:

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;

Ma syntaxe est peut-être loin, parce que je viens de MySQL, mais quelque chose devrait fonctionner similaire.

Si vous voulez que la moyenne, vous pouvez essayer de prendre la moyenne des résultats ci-dessus:

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;

Encore non testé, mais en théorie, je pense que cela devrait fonctionner.

Si mes hypothèses sur ce que vous voulez sont correctes, alors je vois deux façons de le faire.

La voie directe:

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)
    )

La façon délicate:

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

Après tout, les différences moyennes est juste la différence totale divisée par le nombre de divisions dans lesquelles vous le décomposer.

Vous devrez ajouter des clauses WHERE pour la plage de dates si vous voulez limiter par là et vous devez tenir compte de la possibilité de diviser par zéro dans la deuxième requête.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top