我如何将某个 fromdatetime 和 todatetime 分组以获得该时间的 IdelTime

问题描述 投票:0回答:2

我如何获得预期输出:基于此原始数据的空闲时间?

原始数据

时间 超时
2024-09-01 10:00:00 2024-09-01 11:00:00
2024-09-01 10:00:00 2024-09-01 12:00:00
2024-09-01 10:20:00 2024-09-01 13:00:00
2024-09-01 14:00:00 2024-09-01 15:00:00
2024-09-01 15:30:00 2024-09-01 16:00:00

预期产量

时间 超时 持续时间 空闲时间
2024-09-01 10:00:00 2024-09-01 11:00:00 60分钟 0分钟
2024-09-01 10:00:00 2024-09-01 12:00:00 120分钟 0分钟
2024-09-01 10:20:00 2024-09-01 13:00:00 160分钟 0分钟
2024-09-01 14:00:00 2024-09-01 15:00:00 120分钟 60分钟
2024-09-01 15:30:00 2024-09-01 16:00:00 30分钟 30分钟

我达到了持续时间,但在空闲时间中挣扎 我写的查询:

select TimeIn,TimeOut, DATEDIFF(MINUTE, Timein, Timeout) as duration
from [test_idletime]
sql-server
2个回答
0
投票

对于重叠的时间范围,您可能会遇到一些奇怪的重叠场景,其中最后一个

TimeOut
不是来自紧邻的前一行(按
TimeIn
排序)。考虑时间范围:
09:00-10:30, 09:15-10:15, 09:30-10:00, 11:00-12:00
。最后一行计算出的
IdleTime
应该是30分钟,而不是60分钟。

要处理此问题,您需要计算当前的

TimeIn
与之前的
MAX(TimeOut)
TimeIn
的 < current
TimeIn
并进行比较。这可以使用适当约束的窗口函数来计算嵌套查询或CTE中的运行
MAX(TimeOut)
,并在外部/最终查询中计算
IdleTime
来完成。

计算出来的

SELECT
    TimeIn, TimeOut,
    DATEDIFF(MINUTE, TimeIn, TimeOut) as Duration,
    GREATEST(0, DATEDIFF(MINUTE, MaxPriorTimeOut, TimeIn)) as IdleTime
FROM (
    SELECT
        *,
        MAX(TimeOut) OVER(
               ORDER BY TimeIn
               ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
            )AS MaxPriorTimeOut
    FROM Data
) T
ORDER BY TimeIn

GREATEST()
函数在 SQL Server 2022 及更高版本中可用。对于早期版本,您可以使用
CASE
表达式来获得相同的结果。

    CASE WHEN MaxPriorTimeOut < TimeIn
        THEN DATEDIFF(MINUTE, MaxPriorTimeOut, TimeIn)
        ELSE 0 END as IdleTime

结果(带有一些额外的测试数据):

时间 超时 持续时间 空闲时间
2024-09-01 10:00 2024-09-01 11:00 60 0
2024-09-01 10:00 2024-09-01 12:00 120 0
2024-09-01 10:20 2024-09-01 13:00 160 0
2024-09-01 14:00 2024-09-01 15:00 60 60
2024-09-01 15:30 2024-09-01 16:00 30 30
2024-09-02 09:00 2024-09-02 10:30 90 1020
2024-09-02 09:15 2024-09-02 10:15 60 0
2024-09-02 09:30 2024-09-02 10:00 30 0
2024-09-02 11:00 2024-09-02 12:00 60 30

请参阅 this db<>fiddle 进行演示。


0
投票

嗯,我发现了一些东西,但可能可以更即兴创作,任何新的想法都是受欢迎的: 在此输入图片描述

选择 TimeIn、TimeOut、DATEDIFF(MINUTE、Timein、Timeout) 作为持续时间, DATEDIFF(MINUTE, TimeIn, lag(TimeOut) OVER (ORDER BY timeout asc)) < 0 then SUBSTRING(Convert(varchar, DATEDIFF(MINUTE, TimeIn, lag(TimeOut) OVER (ORDER BY timeout))) , 2, 100) -- value came as - to remove - added substing else '0' end as idletime FROM [test_idletime]

© www.soinside.com 2019 - 2024. All rights reserved.