Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 定义时间范围的分钟利用率-T-SQL_Sql Server_Tsql_Ssms - Fatal编程技术网

Sql server 定义时间范围的分钟利用率-T-SQL

Sql server 定义时间范围的分钟利用率-T-SQL,sql-server,tsql,ssms,Sql Server,Tsql,Ssms,我需要计算活动分钟数,给定每行的STARTDT和EndDTS,这些分钟数在定义的时间范围内 例如: RowDTS: [StartDTS=06:36:00][EndDTS=08:42:00] [StartDTS=09:37:00][EndDTS=13:42:00] [StartDTS=14:21:00][EndDTS=18:21:00] 时间框架: [时间帧开始=07:00:00][时间帧结束=15:30:00] 如果StartDTS和EndDTS之间的任何部分时间在时间帧\u Start和时

我需要计算活动分钟数,给定每行的STARTDT和EndDTS,这些分钟数在定义的时间范围内

例如:

RowDTS:

  • [StartDTS=06:36:00][EndDTS=08:42:00]
  • [StartDTS=09:37:00][EndDTS=13:42:00]
  • [StartDTS=14:21:00][EndDTS=18:21:00]
  • 时间框架:

    • [时间帧开始=07:00:00][时间帧结束=15:30:00]
    如果StartDTS和EndDTS之间的任何部分时间在时间帧\u Start和时间帧\u End内,则应计算定义时间帧内的分钟数

    CREATE TABLE #RowDTS (Indentifier varchar(255), StartDTS datetime2(7), EndDTS datetime2(7))
    INSERT INTO #RowDTS
    VALUES
    ('4318','2018-04-03 09:18:00.0000000','2018-04-03 10:20:00.0000000'),
    ('4397','2018-04-20 11:34:00.0000000','2018-04-20 12:27:00.0000000'),
    ('4459','2018-04-20 11:06:00.0000000','2018-04-20 11:54:00.0000000'),
    ('4739','2018-04-12 13:46:00.0000000','2018-04-12 17:34:00.0000000'),
    ('4845','2018-04-18 10:26:00.0000000','2018-04-18 15:18:00.0000000'),
    ('4933','2018-04-19 07:24:00.0000000','2018-04-19 09:51:00.0000000'),
    ('5063','2018-04-03 07:57:00.0000000','2018-04-03 11:00:00.0000000'),
    ('4855','2018-04-03 11:01:00.0000000','2018-04-03 11:51:00.0000000'),
    ('4858','2018-04-05 07:26:00.0000000','2018-04-05 11:12:00.0000000'),
    ('4972','2018-04-11 14:02:00.0000000','2018-04-11 16:36:00.0000000')
    SELECT * FROM #RowDTS
    
    这基本上就是我想要的输出:

    +---------------+-----------------------------+-----------------------------+-----------------+
    | RowIdentifier |          StartDTS           |           EndDTS            | UtilizedMinutes |
    +---------------+-----------------------------+-----------------------------+-----------------+
    |        431859 | 2018-04-03 09:18:00.0000000 | 2018-04-03 10:20:00.0000000 |                 |
    |        439784 | 2018-04-20 11:34:00.0000000 | 2018-04-20 12:27:00.0000000 |                 |
    |        445989 | 2018-04-20 11:06:00.0000000 | 2018-04-20 11:54:00.0000000 |                 |
    |        473939 | 2018-04-12 13:46:00.0000000 | 2018-04-12 17:34:00.0000000 |                 |
    |        484568 | 2018-04-18 10:26:00.0000000 | 2018-04-18 15:18:00.0000000 |                 |
    |        493333 | 2018-04-19 07:24:00.0000000 | 2018-04-19 09:51:00.0000000 |                 |
    |        506386 | 2018-04-03 07:57:00.0000000 | 2018-04-03 11:00:00.0000000 |                 |
    |        485551 | 2018-04-03 11:01:00.0000000 | 2018-04-03 11:51:00.0000000 |                 |
    |        485882 | 2018-04-05 07:26:00.0000000 | 2018-04-05 11:12:00.0000000 |                 |
    |        497230 | 2018-04-11 14:02:00.0000000 | 2018-04-11 16:36:00.0000000 |                 |
    +---------------+-----------------------------+-----------------------------+-----------------+
    

    我假设您的时间范围数据类型是time,并且所有StartDTS和EndDTS值都在同一天内。这个查询可以完成这项工作,但是如果日期值可以分为不同的日期,则需要CTE来获得相同的结果

    DECLARE @TimeFrameStart TIME = '10:00:00';
    DECLARE @TimeFrameEnd TIME = '15:30:00';
    
    SELECT [Indentifier], 
        CONVERT(TIME, [StartDTS]) AS [StartDTS],
        CONVERT(TIME, [EndDTS]) AS [EndDTS],
    
        CASE 
        WHEN CONVERT(TIME, [StartDTS]) >= @TimeFrameStart AND CONVERT(TIME, [EndDTS]) <= @TimeFrameEnd
            THEN DATEDIFF(MINUTE, [StartDTS], [EndDTS])
        WHEN CONVERT(TIME, [StartDTS]) <= @TimeFrameStart AND CONVERT(TIME, [EndDTS]) >= @TimeFrameEnd
            THEN DATEDIFF(MINUTE, @TimeFrameStart, @TimeFrameEnd)
        WHEN CONVERT(TIME, [StartDTS]) <= @TimeFrameStart AND CONVERT(TIME, [EndDTS]) > @TimeFrameStart
            THEN DATEDIFF(MINUTE, @TimeFrameStart, CONVERT(TIME, [EndDTS]))
        WHEN CONVERT(TIME, [EndDTS]) >= @TimeFrameEnd AND CONVERT(TIME, [StartDTS]) < @TimeFrameEnd
            THEN DATEDIFF(MINUTE, CONVERT(TIME, [StartDTS]), @TimeFrameEnd)
        ELSE 0
        END AS [UtilizedMinutes]
    FROM #RowDTS;
    
    DECLARE@TimeFrameStart TIME='10:00:00';
    声明@TimeFrameEnd TIME='15:30:00';
    选择[标识符],
    将(时间,[StartDTS])转换为[StartDTS],
    将(时间[EndDTS])转换为[EndDTS],
    案例
    当CONVERT(TIME,[StartDTS])>=@TimeFrameStart和CONVERT(TIME,[EndDTS])=@TimeFrameEnd和CONVERT(TIME,[StartDTS])<@TimeFrameEnd
    然后是DATEDIFF(分钟,转换(时间,[StartDTS]),@TimeFrameEnd)
    其他0
    结束时为[实用数字]
    来自#RowDTS;
    
    这是该列中的文字值吗?不,这是任意时间。希望确保并说明某些时间可能在时间范围之前或之后重叠,有些时间可能完全包含在时间范围内。您能提供DDL吗?该列看起来像一个VARCHAR,底层列的数据类型是什么?很抱歉,我将第一次更新示例数据!这很好用,非常感谢你的帮助!另一种方法是使用
    DateDiff()
    和两个
    case
    表达式作为参数:一个用于确定开始时间,另一个用于确定结束时间。SQL Server的现代版本可以使用而不是
    case
    来实现更紧凑的解决方案。您是否愿意进一步创建一个CTE来说明可能跨越午夜的时间范围?