找工作时间比例的停机时间

时间:2013-03-25 11:41:48

标签: sql-server-2008

关于管理受支持系统的停机时间,我希望能够从我的呼叫处理数据库报告在支持的时间内停机时间有多少。支持的小时数仅为工作日的9-5。因此,如果一个系统在周五中午停止运行并在接下来的周二中午重新启动,我需要记录16小时的停机时间: 12-5周五5小时 星期一8小时 9-12周二3小时。

理想情况下,我也想排除银行假期,但任何帮助将不胜感激。谢谢。 戴夫。

1 个答案:

答案 0 :(得分:0)

首先假设报告采用2个参数@ t1 DATETIME,@ t2 DATETIME其中@ t1,@ t2是您要报告的期间的开始和结束时间。

我会创建一个包含所有支持时间段的表格,例如所有连续支持期的CREATE TABLE SupportTime(StartSupport DATETIME,EndSupport DATETIME)。 (如果跨越几年,这可能包含很多行但不应该太难生成)。

让我们假设有一个类似的表CREATE TABLE DownTime(StartDownTime DATETIME,EndDownTime DATETIME),其中包含所有停机时间段。

所需的报告查询应如下所示:

WITH CTE AS (
    SELECT
        CASE WHEN StartSupport < @t1 THEN @t1 ELSE StartSupport END AS StartSupport, 
        CASE WHEN EndSupport > @t2 THEN @t2 ELSE EndSupport END AS EndSupport
        FROM SupportTime
        WHERE @t1 <= EndSupport
        AND @t2 >= StartSupport)

SELECT
    SUM(
       DATEDIFF (mi,
       CASE WHEN dt.StartDownTime < CTE.StartSupport THEN CTE.StartSupport ELSE dt.StartDownTime END,
       CASE WHEN dt.EndDownTime > CTE.EndSupport THEN CTE.EndSupport ELSE dt.EndDownTime)
   ) As DownTimeMinutes, -- Total of down time during support time (mins)
FROM DownTime AS dt
INNER JOIN CTE ON (CTE.StartSupport <= dt.EndDownTime
                   AND CTE.EndSupport >= dt.StartDownTime)

SELECT SUM(DATEDIFF(mi, CTE.StartSupport, CTE.EndSupport)) AS SupportTimeMins

我将尝试解释发生了什么 - 如果开始报告时间或结束报告时间在支持期内,虚拟CTE表包含调整StartSupport或EndSupport的报告日期之间的所有相关支持期。 CTE与DownTime表的JOIN对所有相关记录的StartDownTime和EndDownTime之间的差值进行求和(如果它们落在StartSupportTime或EndSupport之外,则再次调整StartDownTime和EndDownTime)。