我想从下面的表1中取出时差的平均值。这些值不是连续的,偶尔会重复时间值,所以我需要1)按时间排序,2)丢弃非唯一值,3)执行时间差(以毫秒为单位),然后4)平均得到的时间差值。此外,我想5)将datediff操作限制在选定的时间范围内,例如 WHERE _TimeStamp> ='20091220 11:59:56.1'AND _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
答案 0 :(得分:1)
第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;
尚未经过测试,但从理论上讲,我认为它应该可行。
答案 1 :(得分:1)
如果我对你想要的东西的假设是正确的,那么我会看到两种方法。
直接的方式:
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
毕竟,平均差异只是总差异除以你将其分解的分割数量。
如果您想要限制日期范围,则需要添加WHERE子句,并且您需要考虑在第二个查询中除以零的可能性。
答案 2 :(得分:1)
这是一个有效且不丑的:
;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)