SQL Demo 这个我的表与demo中的相同,我使用相同的查询。我需要得到所有特定员工的总持续时间......我试了很多..
select
id, cast(time_stamp as date) [date]
, format(max(case when in_rank = 1 then time_stamp end),'HH:mm') check_in_1
, format(max(case when in_rank = 1 then next_timestamp end),'HH:mm') check_out_1
, format(max(case when in_rank = 1 then
dateadd(ss,datediff(ss,time_stamp,next_timestamp),0)
end),'HH:mm') total_hrs_1
, format(max(case when in_rank = 2 then time_stamp end),'HH:mm') check_in_2
, format(max(case when in_rank = 2 then next_timestamp end),'HH:mm') check_out_2
, format(max(case when in_rank = 2 then
dateadd(ss,datediff(ss,time_stamp,next_timestamp),0)
end),'HH:mm') total_hrs_2
from (
select
id, time_stamp, AccessType, next_timestamp, next_accesstype
, dense_rank() over(partition by id, cast(time_stamp as date) order by time_stamp) in_rank
from table1 t1
outer apply (
select top(1) t2.time_stamp, t2.AccessType
from table1 t2
where t1.id = t2.id and t1.AccessType <> t2.AccessType
and cast(t1.time_stamp as date) = cast(t2.time_stamp as date)
and t1.time_stamp < t2.time_stamp
order by t2.time_stamp
) oa (next_timestamp, next_accesstype)
where AccessType = 0
) d
group by id, cast(time_stamp as date)
预期产出:
id date check_in_1 check_out_1 total_hrs_1 check_in_2 check_out_2 total_hrs_2 Grand Total
1001 2017-09-05 09:35 12:00 02:25 09:36 12:00 02:24 4:49
1002 2017-09-05 11:00 12:25 01:25 14:00 18:00 04:00 5:25
任何人都帮助我得到这个......我尝试了很多次
答案 0 :(得分:0)
使用SQL Demo中的示例数据我已经修改了您的查询 - 请参阅代码中的注释
--I'm using a CTE only because to avoid the messy looking way of calculating the Grand total otherwise
;WITH cteX
AS(
SELECT
id, cast(time_stamp as date) [date]
, format(max(case when in_rank = 1 then time_stamp end),'HH:mm') check_in_1
, format(max(case when in_rank = 1 then next_timestamp end),'HH:mm') check_out_1
, format(max(case when in_rank = 1 then
dateadd(SECOND,datediff(SECOND,time_stamp,next_timestamp),0)
end),'HH:mm') total_hrs_1
, format(max(case when in_rank = 2 then time_stamp end),'HH:mm') check_in_2
, format(max(case when in_rank = 2 then next_timestamp end),'HH:mm') check_out_2
, format(max(case when in_rank = 2 then
dateadd(SECOND,datediff(SECOND,time_stamp,next_timestamp),0)
end),'HH:mm') total_hrs_2
--additional two rows here to represent the number of second between checkin and checkout
, Total_hrs_1_secs = MAX(case when in_rank = 1 then
datediff(SECOND,time_stamp,next_timestamp) end)
, Total_hrs_2_secs = MAX(case when in_rank = 2 then
datediff(SECOND,time_stamp,next_timestamp) end)
from (
select
id, time_stamp, AccessType, next_timestamp, next_accesstype
, dense_rank() over(partition by id, cast(time_stamp as date) order by time_stamp) in_rank
from table1 t1
outer apply (
select top(1) t2.time_stamp, t2.AccessType
from table1 t2
where t1.id = t2.id and t1.AccessType <> t2.AccessType
and cast(t1.time_stamp as date) = cast(t2.time_stamp as date)
and t1.time_stamp < t2.time_stamp
order by t2.time_stamp
) oa (next_timestamp, next_accesstype)
where AccessType = 0
) d
group by id, cast(time_stamp as date)
)
SELECT X.id
, X.date
, X.check_in_1
, X.check_out_1
, X.total_hrs_1
, X.check_in_2
, X.check_out_2
, X.total_hrs_2
--show the Grant total using the seconds rows from above
, GrandTotal = CONVERT(TIME(0), DATEADD(SECOND,(X.Total_hrs_1_secs + X.Total_hrs_2_secs),0),108)
FROM cteX X
输出
答案 1 :(得分:0)
您在一天内有超过2对登录/注销,因此计算“in_row”以输出额外的登录/注销;
MS SQL Server 2014架构设置:
CREATE TABLE Table1
([id] int, [time_stamp] datetime, [AccessType] varchar(3))
;
INSERT INTO Table1
([id], [time_stamp], [AccessType])
VALUES
(1001, '2017-09-05 09:35:00', 0),
(1001, '2017-09-05 09:36:00', 0),
(1001, '2017-09-05 09:37:00', 0),
(1002, '2017-09-05 11:00:00', 0),
(1001, '2017-09-05 12:00:00', 1),
(1002, '2017-09-05 12:25:00', 1),
(1001, '2017-09-05 13:00:00', 0),
(1002, '2017-09-05 14:00:00', 0),
(1001, '2017-09-05 17:00:00', 1),
(1002, '2017-09-05 18:00:00', 1)
;
查询1 :
select
id, in_row, cast(time_stamp as date) [date]
, format(max(case when in_rank = 1 then time_stamp end),'HH:mm') check_in_1
, format(max(case when in_rank = 1 then next_timestamp end),'HH:mm') check_out_1
, format(max(case when in_rank = 1 then
dateadd(ss,datediff(ss,time_stamp,next_timestamp),0)
end),'HH:mm') total_hrs_1
, format(max(case when in_rank = 0 then time_stamp end),'HH:mm') check_in_2
, format(max(case when in_rank = 0 then next_timestamp end),'HH:mm') check_out_2
, format(max(case when in_rank = 0 then
dateadd(ss,datediff(ss,time_stamp,next_timestamp),0)
end),'HH:mm') total_hrs_2
, format(max(case when in_rank = 0 then
dateadd(ss,datediff(ss,time_stamp,next_timestamp),0)
end),'HH:mm') total_hrs_2
, format(dateadd(ss,sum(secs_diff),0),'HH:mm') total_hrs
from (
select
id, time_stamp, AccessType, next_timestamp, next_accesstype
, datediff(ss,time_stamp,next_timestamp) secs_diff
, dense_rank() over(partition by id, cast(time_stamp as date) order by time_stamp) % 2 in_rank
, (count(*) over(partition by id, cast(time_stamp as date) order by time_stamp) + 1) / 2 in_row
from table1 t1
outer apply (
select top(1) t2.time_stamp, t2.AccessType
from table1 t2
where t1.id = t2.id and t1.AccessType <> t2.AccessType
and cast(t1.time_stamp as date) = cast(t2.time_stamp as date)
and t1.time_stamp < t2.time_stamp
order by t2.time_stamp
) oa (next_timestamp, next_accesstype)
where AccessType = 0
) d
group by id, in_row, cast(time_stamp as date)
<强> Results 强>:
| id | in_row | date | check_in_1 | check_out_1 | total_hrs_1 | check_in_2 | check_out_2 | total_hrs_2 | total_hrs_2 | total_hrs |
|------|--------|------------|------------|-------------|-------------|------------|-------------|-------------|-------------|-----------|
| 1001 | 1 | 2017-09-05 | 09:35 | 12:00 | 02:25 | 09:36 | 12:00 | 02:24 | 02:24 | 04:49 |
| 1001 | 2 | 2017-09-05 | 09:37 | 12:00 | 02:23 | 13:00 | 17:00 | 04:00 | 04:00 | 06:23 |
| 1002 | 1 | 2017-09-05 | 11:00 | 12:25 | 01:25 | 14:00 | 18:00 | 04:00 | 04:00 | 05:25 |
答案 2 :(得分:0)
这给出了上面提到的确切结果:
select
id, cast(time_stamp as date) [date]
, format(max(case when in_rank = 1 then time_stamp end),'HH:mm') check_in_1
, format(max(case when in_rank = 1 then next_timestamp end),'HH:mm') check_out_1
, format(max(case when in_rank = 1 then
dateadd(ss,datediff(ss,time_stamp,next_timestamp),0)
end),'HH:mm') total_hrs_1
, format(max(case when in_rank = 2 then time_stamp end),'HH:mm') check_in_2
, format(max(case when in_rank = 2 then next_timestamp end),'HH:mm') check_out_2
, format(max(case when in_rank = 2 then
dateadd(ss,datediff(ss,time_stamp,next_timestamp),0)
end),'HH:mm') total_hrs_2
, format(dateadd(ss,sum(secs_diff),0),'HH:mm') Total_Hrs
from (
select
id, time_stamp, AccessType, next_timestamp, next_accesstype, datediff(ss,time_stamp,next_timestamp) secs_diff
, dense_rank() over(partition by id, cast(time_stamp as date) order by time_stamp) in_rank
from table1 t1
outer apply (
select top(1) t2.time_stamp, t2.AccessType
from table1 t2
where t1.id = t2.id and t1.AccessType <> t2.AccessType
and cast(t1.time_stamp as date) = cast(t2.time_stamp as date)
and t1.time_stamp < t2.time_stamp
order by t2.time_stamp
) oa (next_timestamp, next_accesstype)
where AccessType = 0
) d
group by id, cast(time_stamp as date)