开始和结束之间的总日期时间持续时间

Sum datetime durations between start and end

我有一个 table 跟踪一个具有开始和结束日期时间列的整数状态变量。另一个程序在它监视的状态变量发生变化时更新 table。它将最后一个条目的 end_timestamp 设置为当前时间,并插入一个新的状态行,当前时间为 start_timestamp。这样做的结果是当前经过的状态持续时间的 end_timestamp 为 Null。

外观如下:

我正在尝试找到查询每个状态持续时间的最佳方法,以秒为单位,在给定的开始和结束日期时间之间。将干净地落在提供的端点内的状态持续时间相加是微不足道的,但我不确定处理边缘的最佳方法。我以前在数据库之外做过这个,通过找到最晚开始和最早结束,得到差异,并增加总和。

这是我当前对求和持续时间的查询,包括当前经过的持续时间:

SELECT status, sum(datediff(S, start_timestamp, ISNULL([end_timestamp], GETDATE()))) as duration
FROM [status_table]
WHERE start_timestamp >= @start AND
(end_timestamp <= @end OR end_timestamp is Null)
GROUP BY status;

示例结果:

视觉参考:

只需将 case 语句添加到您的 SUM 中,并确保您的 where 检查开始日期和结束日期是否在 BETWEEN

之间
select  [status],
        sum(datediff(
            second, 
            case when start_timestamp < @start then @start else start_timestamp end, 
            case when end_timestamp is null or end_timestamp > @end then @end else end_timestamp end
            )
        ) as duration
from    status_table
where   (@start <= isnull(end_timestamp,@end))
and     (end_timestamp IS NULL or @end  >= end_timestamp)
group by [status]

更新

尝试保持查询可搜索

select      [status],
            sum(datediff(second, startdt, enddt)) as duration
from        (
                select      [status],   
                            case when start_timestamp < @start then @start else start_timestamp end as startdt,
                            case when end_timestamp is null or end_timestamp > @end then @end else end_timestamp end as enddt
                from        status_table
                where       (start_timestamp < @end)
                and         (end_timestamp is null or end_timestamp > @start)
) t
group by    [status]