员工状态日期时间的高级聚合数据透视表
Advanced aggregate pivot on datetime for employee status
我正在使用 table 存储各种状态类型的时间戳,我希望它能够旋转以更清楚地了解每个员工的实际 "busy" 时间......(所以我可以 运行 工作 load/stats)
有几个注意事项..
员工在进行中可能会误给自己分配两次(示例数据中EMP1见第5行),我希望pivot使用最早的时间
员工可以将自己设置为 FRO 或 FRV(两者都是新任务免费的变体)因此无论员工是 FRO 还是 FRV,它都应该在 FREE 列中显示两种状态类型中的任何一种
状态类型:
- ST = Start/Assigned
- IP = 进行中
- FRV = 车内免费
- FRO = 有空
状态 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.
我正在使用 table 存储各种状态类型的时间戳,我希望它能够旋转以更清楚地了解每个员工的实际 "busy" 时间......(所以我可以 运行 工作 load/stats)
有几个注意事项..
员工在进行中可能会误给自己分配两次(示例数据中EMP1见第5行),我希望pivot使用最早的时间
员工可以将自己设置为 FRO 或 FRV(两者都是新任务免费的变体)因此无论员工是 FRO 还是 FRV,它都应该在 FREE 列中显示两种状态类型中的任何一种
状态类型:
- ST = Start/Assigned
- IP = 进行中
- FRV = 车内免费
- FRO = 有空
状态 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.