员工状态日期时间的高级聚合数据透视表

Advanced aggregate pivot on datetime for employee status

我正在使用 table 存储各种状态类型的时间戳,我希望它能够旋转以更清楚地了解每个员工的实际 "busy" 时间......(所以我可以 运行 工作 load/stats)

有几个注意事项..

状态类型:

状态 table 的示例数据:

 DateTime              emp      status
 3/26/2017 14:20:30    EMP1      ST
 3/26/2017 14:21:16    EMP1      FRO
 3/26/2017 14:26:11    EMP1      ST
 3/26/2017 14:26:42    EMP1      IP
 3/26/2017 14:26:45    EMP1      IP
 3/26/2017 14:28:35    EMP1      FRO
 3/26/2017 14:21:15    EMP2      ST
 3/26/2017 14:22:35    EMP2      IP
 3/26/2017 14:55:53    EMP2      FRV
 3/26/2017 14:20:48    EMP3      ST
 3/26/2017 14:23:49    EMP3      FRV

旋转后的预期结果如下所示:
(ST = 开始,IP = 进行中,FREE = 不忙)

emp     ST                      IP                     FREE        
EMP1    3/26/2017 14:20:30      null                   3/26/2017 14:21:16
EMP1    3/26/2017 14:26:11      3/26/2017 14:26:42     3/26/2017 14:28:35
EMP2    3/26/2017 14:21:15      3/26/2017 14:22:35     3/26/2017 14:55:53
EMP3    3/26/2017 14:20:48      null                   3/26/2017 14:23:49

使用示例数据测试 table。

CREATE TABLE test (
      [DateTime] [datetime] NULL,
      [emp] [varchar](6) NOT NULL,
      [status] [varchar](6) NOT NULL
      )

INSERT INTO test values 
('2017-03-26 14:20:30.000', 'EMP1', 'ST'),
('2017-03-26 14:21:16.000', 'EMP1', 'FRO'),
('2017-03-26 14:26:11.000', 'EMP1', 'ST'),
('2017-03-26 14:26:42.000', 'EMP1', 'IP'),
('2017-03-26 14:26:45.000', 'EMP1', 'IP'),
('2017-03-26 14:28:35.000', 'EMP1', 'FRO'),
('2017-03-26 14:21:15.000', 'EMP2', 'ST'),
('2017-03-26 14:22:35.000', 'EMP2', 'IP'),
('2017-03-26 14:55:53.000', 'EMP2', 'FRV'),
('2017-03-26 14:20:48.000', 'EMP3', 'ST'),
('2017-03-26 14:23:49.000', 'EMP3', 'FRV')

非常感谢任何帮助,如果请求太模糊,很乐意进一步解释……

谢谢

我将此逻辑视为:您想根据每次开始对记录进行分组。一旦有了组,剩下的就是聚合了。

在 SQL Server 2012+ 中,分配组很容易。 . .它是每条记录的启动次数的累加和。在 SQL Server 2008 中,这更棘手。但是你可以用一个相关的子查询来做到这一点:

select emp,
       min(case when status = 'ST' then datetime end) as st,
       min(case when status = 'IP' then datetime end) as ip,
       max(case when status in ('FRQ', 'FRV') then datetime end) as fr
from (select t.*,
             (select count(*)
              from test t2
              where t2.emp = t.emp and t2.datetime <= t.datetime and
                    t2.status = 'ST'
             ) as grp
      from test t
     ) t
group by emp, grp;

Here 是 SQL Fiddle.