表中非连续行之间的 Datediff

发布于 2024-08-17 15:28:21 字数 428 浏览 7 评论 0原文

我想从下面的表 1 中取时间差的平均值。这些值不连续,有时时间值会重复,因此我需要 1)按时间排序,2)丢弃非唯一值,3)执行时间差(以毫秒为单位),然后 4)平均结果时间差价值观。此外,我想 5)将 datediff 操作限制在选定的时间范围内,例如 其中 _TimeStamp >= '20091220 11:59:56.1' 且 _TimeStamp <= _TimeStamp >= '20091220 11:59:56.8'。我很困惑如何将这一切组合在一起!

表1:
_时间戳
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

I would like to take the average of the time difference from Table1 below. The values are not consecutive and occasionally the time value is repeated, so I need to 1) sort by time, 2) discard non-unique values, 3) perform the time difference (in milliseconds), then 4) average the resulting time difference values. Further I'd like to 5) limit the datediff operation to a chosen time range, such as
WHERE _TimeStamp >= '20091220 11:59:56.1' AND _TimeStamp <= _TimeStamp >= '20091220 11:59:56.8'. I am pretty stumped how to put this all together!

Table1:
_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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

想你的星星会说话 2024-08-24 15:28:21

这是一个有效且不难看的:

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

Here's one that works and is not ugly:

;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

Will give you the following output from your example:

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: If you want to restrict time ranges then just add WHERE _Timestamp BETWEEN @StartDate AND @EndDate before the GROUP BY line.

Edit2: And if you want the average, then change that final SELECT t1.dt, ... statement to:

SELECT AVG(DATEDIFF(MS, t1.dt, t2.dt))
FROM Time_CTE t1 ... (same as above)
╭ゆ眷念 2024-08-24 15:28:21

步骤 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;

尚未测试,但理论上,我认为它应该有效。

Step 1 is to select only unique times:

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

Then, if you want to, say, compare all times with each other (not sure how you want to select times), you could do something crazy like:

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;

My syntax might be off, because I'm coming from MySQL, but something similar should work.

If you want the average, you could try taking the average of the above results:

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;

Still untested, but in theory, I think it should work.

廻憶裏菂餘溫 2024-08-24 15:28:21

如果我对你想要的东西的假设是正确的,那么我会看到两种方法。

直接的方法:

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 子句,并且需要考虑在第二个查询中除以零的可能性。

If my assumptions on what you want are correct, then I see two ways of doing it.

The direct way:

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

The tricky way:

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

After all, the average differences is just the total difference divided by the number of divisions into which you're breaking it down.

You'll need to add WHERE clauses for the date range if you want to limit by that and you will need to account for the possibility of divide by zero in the second query.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文