你可以试试这个。
通过Status 在CTE 中创建一个row_number,因为我们需要知道哪个暂停时间对应哪个恢复时间。然后self join 在CTE by EmployeeId
CREATE TABLE T(
Id INT,
EmployeeId INT,
ScanDateTime DATETIME,
Status INT
);
INSERT INTO T VALUES (7 ,87008 ,'2018-08-02 16:03:00.227',1);
INSERT INTO T VALUES (8 ,87008 ,'2018-08-02 16:06:17.277',2);
INSERT INTO T VALUES (9 ,87008 ,'2018-08-02 16:10:37.107',3);
INSERT INTO T VALUES (10,87008 ,'2018-08-02 16:20:17.277',2);
INSERT INTO T VALUES (11,87008 ,'2018-08-02 16:30:37.107',3);
INSERT INTO T VALUES (12,87008 ,'2018-08-02 20:06:00.000',4);
查询 1:
;with cte as(
SELECT *,
MIN(ScanDateTime) over(partition by EmployeeId order by EmployeeId) StartTime,
MAX(ScanDateTime) over(partition by EmployeeId order by EmployeeId) EndTime,
ROW_NUMBER() OVER(PARTITION BY Status order by id) rn
FROM t
)
select t1.EmployeeId,
t1.StartTime,
t1.EndTime,
SUM(datediff(minute,t1.ScanDateTime,t2.ScanDateTime)) BreakInMins
from
cte t1
inner join cte t2
on t1.rn =t2.rn and t1.Status = 2 and t2.Status = 3 and t1.EmployeeId = t2.EmployeeId
group by t1.EmployeeId,
t1.StartTime,
t1.EndTime
Results:
| EmployeeId | StartTime | EndTime | BreakInMins |
|------------|----------------------|--------------------------|-------------|
| 87008 | 2018-08-02T20:06:00Z | 2018-08-02T16:03:00.227Z | 14 |
编辑
如果您的数据中有不同的日期,您可以尝试此查询。只需按date 分组即可。
CREATE TABLE T(
Id INT,
EmployeeId INT,
ScanDateTime DATETIME,
Status INT
);
INSERT INTO T VALUES (7 ,87008 ,'2018-08-02 16:03:00.227',1);
INSERT INTO T VALUES (8 ,87008 ,'2018-08-02 16:06:17.277',2);
INSERT INTO T VALUES (9 ,87008 ,'2018-08-02 16:10:37.107',3);
INSERT INTO T VALUES (10,87008 ,'2018-08-02 16:20:17.277',2);
INSERT INTO T VALUES (11,87008 ,'2018-08-02 16:30:37.107',3);
INSERT INTO T VALUES (12,87008 ,'2018-08-02 20:06:00.000',4);
INSERT INTO T VALUES (27 ,87008 ,'2018-08-03 16:03:00.227',1);
INSERT INTO T VALUES (28 ,87008 ,'2018-08-03 16:06:17.277',2);
INSERT INTO T VALUES (29 ,87008 ,'2018-08-03 16:11:37.107',3);
INSERT INTO T VALUES (210,87008 ,'2018-08-03 16:20:17.277',2);
INSERT INTO T VALUES (211,87008 ,'2018-08-03 16:30:37.107',3);
INSERT INTO T VALUES (212,87008 ,'2018-08-03 20:06:00.000',4);
查询 1:
;with cte as(
SELECT EmployeeId,
MAX(CASE WHEN Status = 1 then ScanDateTime end) StartTime,
MIN(CASE WHEN Status = 4 then ScanDateTime end) EndTime,
CAST(ScanDateTime as date) dt
FROM t
GROUP BY EmployeeId,CAST(ScanDateTime as date)
)
,cte2 as(
SELECT t2.*,
Row_number() over(partition by t2.EmployeeId,t2.Status order by Id) rn,
t1.StartTime,
t1.EndTime,
t1.dt
FROM cte t1
INNER JOIN T t2 ON t1.EmployeeId = t2.EmployeeId and Status in (2,3) and t1.dt = CAST(t2.ScanDateTime as date)
)
select t1.EmployeeId,
t1.StartTime,
t1.EndTime,
SUM(datediff(minute,t1.ScanDateTime,t2.ScanDateTime)) BreakInMins
from cte2 t1
inner join cte2 t2 on
t1.rn = t2.rn
and
t1.EmployeeId = t2.EmployeeId
and t1.Status = 2 and t2.Status =3
group by t1.EmployeeId,
t1.StartTime,
t1.EndTime
Results:
| EmployeeId | StartTime | EndTime | BreakInMins |
|------------|--------------------------|----------------------|-------------|
| 87008 | 2018-08-02T16:03:00.227Z | 2018-08-02T20:06:00Z | 14 |
| 87008 | 2018-08-03T16:03:00.227Z | 2018-08-03T20:06:00Z | 15 |