如何计算列值变化的时间差?

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

我正在尝试编写一个查询,以获得相对于SQL Server 2012中的列中的值更改的累积时间差异。

我正在尝试收集一些关于任务在另一个用户上等待的时间的分析,在此任务中有2个参与者Role = 0是实施者,Role = 1是任务的审阅者。通过任务的持续时间,实施者和审阅者可以多次执行关于任务的活动。目的是为审核人和实施者提供待处理的总时间。要重新创建数据快照,请参阅下面的示例

CREATE TABLE ActivityTable
([Id] [int] IDENTITY(1,1) NOT NULL,
[RoleId] [int] NULL,
[ActivityDate] [DATETIME] NULL)

INSERT INTO [ActivityTable] VALUES (1, '2018-10-19 13:00:19.840')
INSERT INTO [ActivityTable] VALUES (1, '2018-10-19 13:00:18.073')
INSERT INTO [ActivityTable] VALUES (1, '2018-10-19 12:59:48.417')
INSERT INTO [ActivityTable] VALUES (0, '2018-10-15 13:48:00.557')
INSERT INTO [ActivityTable] VALUES (0, '2018-10-15 12:56:25.567')
INSERT INTO [ActivityTable] VALUES (0, '2018-10-15 12:56:09.967')
INSERT INTO [ActivityTable] VALUES (0, '2018-10-15 12:55:26.500')
INSERT INTO [ActivityTable] VALUES (0, '2018-10-15 12:53:17.997')
INSERT INTO [ActivityTable] VALUES (1, '2018-10-15 12:36:17.967')
INSERT INTO [ActivityTable] VALUES (1, '2018-10-15 12:35:38.497')
INSERT INTO [ActivityTable] VALUES (1, '2018-10-15 12:33:05.860')
INSERT INTO [ActivityTable] VALUES (1, '2018-10-15 12:32:07.793')
INSERT INTO [ActivityTable] VALUES (1, '2018-10-15 12:32:00.010')
INSERT INTO [ActivityTable] VALUES (0, '2018-10-15 12:18:18.417')
INSERT INTO [ActivityTable] VALUES (0, '2018-10-15 12:17:16.370')
INSERT INTO [ActivityTable] VALUES (0, '2018-10-15 12:11:48.590')
INSERT INTO [ActivityTable] VALUES (0, '2018-10-15 11:58:38.557')
INSERT INTO [ActivityTable] VALUES (0, '2018-10-15 11:56:23.820')`

所以每次转换的总时间看起来像

RoleInfo  Start Time               End Time                 Duration Minutes
0         2018-10-15 11:56:23.820  2018-10-15 12:32:00.010  37
1         2018-10-15 12:32:00.010  2018-10-15 12:53:17.997  22
0         2018-10-15 12:53:17.997  2018-10-19 12:59:48.417  5767
1         2018-10-19 12:59:48.417  2018-10-19 13:00:19.840  1

预期的最终结果是未决时间的汇总

RoleInfo  Duration in Minutes
0         5804
1         23
sql-server
1个回答
0
投票

请参阅查询中的注释。

单独执行每个内部查询以查看结果以便更好地理解

select  RoleId, Duration = sum(datediff(minute, StartTime, EndTime))
from
(
    -- perform a group by RoleId + grp
    -- min() and max() on ActivityDate will gives you based on RoleId
    -- however you wanted the StartTime of next RoleId. For this LEAD() OVER() is used
    select  RoleId, 
            StartTime = min(ActivityDate), 
            EndTime   = coalesce(lead(min(ActivityDate)) over (order by min(ActivityDate)), 
                                 max(ActivityDate))
    from
    (
        -- identify the group. each group is continuous same RoleId value
        select  *, grp = Id - dense_rank() over (partition by RoleId 
                                                     order by ActivityDate desc)
        from    ActivityTable
    ) a
    group by RoleId, grp
) b
group by RoleId

顺便说一句,我认为你发布的预期结果是错误的

/* RESULT
    RoleId  Duration
    0       5802
    1       22
*/
© www.soinside.com 2019 - 2024. All rights reserved.