Вопрос

Я хотел бы получить среднее значение разницы во времени из таблицы 1 ниже. Значения не являются последовательными, и иногда значение времени повторяется, поэтому мне нужно 1) сортировку по времени, 2) отказаться от неника ценности. Кроме того, я хотел бы 5) ограничить операцию датчика выбранным временным диапазоном, например, где _timestamp> = '20091220 11: 59: 56,1' и _timestamp <= _timestamp> = '20091220 11: 59: 56,8'. Я довольно озадачен, как собрать все это вместе!

Таблица 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

Это было полезно?

Решение

Вот тот, который работает и не уродлив:

;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

Даст вам следующий вывод из вашего примера:

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

РЕДАКТИРОВАТЬ: Если вы хотите ограничить диапазоны времени, просто добавьте WHERE _Timestamp BETWEEN @StartDate AND @EndDate перед GROUP BY линия.

Edit2: и если вы хотите среднего, тогда измените это окончательное SELECT t1.dt, ... заявление к:

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

Другие советы

Шаг 1 - выбрать только уникальное время:

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

Тогда, если вы хотите, скажем, сравнивайте все время друг с другом (не уверены, как вы хотите выбрать время), вы можете сделать что -то сумасшедшее, как:

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;

Мой синтаксис может быть отключен, потому что я прихожу из MySQL, но что -то подобное должно работать.

Если вы хотите среднего, вы можете попробовать получить среднее значение вышеуказанных результатов:

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;

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

Если мои предположения о том, что вы хотите, верны, то я вижу два способа сделать это.

Прямой путь:

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

Сложный путь:

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

В конце концов, средние различия - это всего лишь общая разница, деленная на количество подразделений, в которые вы ее разрушаете.

Вам нужно добавить, где положения для диапазона дат, если вы хотите ограничить это, и вам нужно будет учесть возможность разделения на ноль во втором запросе.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top