如何通过查看过去的签到时间来区分白班和夜班?
How to distinguish between day and night shifts by looking at past sign in times?
目前,报告使用预定义的时间。但有时员工会超时工作,他们会偷偷进入下一个班次报告。如何修改报告查询以查看过去的登录时间以避免这种情况?在TIMEATT
列中,1
是入口,2
是出口。浅蓝色突出显示正确的条目,黄色表示错误的条目。
29 日的白班报告有“完成,简的”夜班入职时间
29 号的夜班报告有白班的“Do,Jone's”进入时间
下面的查询创建了一个临时文件 table,其中的数据与屏幕截图中的数据相同。
CREATE TABLE #temptable ( [Company] nvarchar(60), [ID] int, [NAME] nvarchar(130), [TIMEATT] int, [Time_CST] datetime )
INSERT INTO #temptable
values
( N'Company Ltd.', 11111, N'Done, Jane', 1, N'2019-04-28T18:00:27' ),
( N'Company Ltd.', 11111, N'Done, Jane', 1, N'2019-04-28T18:00:28' ), --Sometimes people tap their card twice
( N'Company Ltd.', 11111, N'Done, Jane', 2, N'2019-04-29T06:00:55' ),
( N'Company Ltd.', 11111, N'Done, Jane', 1, N'2019-04-29T06:01:55' ),
( N'Company Ltd.', 11111, N'Done, Jane', 2, N'2019-04-29T06:04:55' ),
( N'Company Ltd.', 11111, N'Done, Jane', 1, N'2019-04-29T18:00:27' ),
( N'Company Ltd.', 11111, N'Done, Jane', 2, N'2019-04-30T06:13:55' ),
( N'Company Ltd.', 22222, N'Do, Jone', 1, N'2019-04-29T06:20:17' ),
( N'Company Ltd.', 22222, N'Do, Jone', 2, N'2019-04-29T06:47:12' ),
( N'Company Ltd.', 22222, N'Do, Jone', 1, N'2019-04-29T10:33:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 2, N'2019-04-29T18:05:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 1, N'2019-04-29T18:06:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 2, N'2019-04-29T18:09:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 1, N'2019-04-30T06:05:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 2, N'2019-04-30T16:05:33' )
-- Test table
-- 1 is entry and 2 is exit. Sometimes people double swipe their cards which results in two 1 entries.
select * from #temptable as T
--Report start
set deadlock_priority low;
declare @shift varchar(10) = 'night'; --Option to switch between day and night
declare @reportdate datetime = '2019-04-29'; --Date to be ran
declare @starttime datetime;
declare @endtime datetime;
select @starttime = (case
when @shift = 'day' then
convert(datetime, @reportdate) + cast('04:00:00.000' as datetime)
when @shift = 'night' then
convert(datetime, @reportdate) + cast('16:00:00.000' as datetime)
end
);
select @endtime = (case
when @shift = 'day' then
convert(datetime, @reportdate) + cast('23:59:59.000' as datetime)
when @shift = 'night' then
convert(datetime, dateadd(d, 1, @reportdate)) + cast('11:59:59.000' as datetime)
end
);
select Company
, NAME
, EmpID
, startTime
, endTime
, sum(datediff(second, startTime, endTime) / 3600.0) as HrsWorked
from
( -- sub query to get matching exit time for each entry if it exists
select Company
, NAME
, ID as EmpID
, Time_CST as startTime
, lead(Time_CST, 1, null) over (partition by NAME order by Time_CST) as endTime
, TIMEATT
, Time_CST
from
( -- subquery to exclude duplicate records
select *
from
(
select *
from
( -- subquery to identify records to ignore
select Company
, NAME
, ID
, TIMEATT
, Time_CST
, case lead(TIMEATT, 1, 0) over (partition by NAME order by Time_CST)
when TIMEATT then
1
else
0
end as Exclude
from #temptable
) a
where Exclude = 0
) t
) n
) z
where TIMEATT = 1 -- filter so left column is always entry time.
and startTime >= @starttime
and endTime <= @endtime
--and Company in (@contractornames)
group by z.Company
, z.NAME
, z.EmpID
, z.startTime
, z.endTime
order by Company
, NAME
, startTime
--DROP TABLE #temptable
首先,我将您的查询更改为使用 CTE 而不是 3 级子查询。使其更易于阅读。
为了识别错误的打孔,我在您的查询中扩展了 CASE 语句,该语句识别重复的打孔并将它们标记为排除。使用 LEAD 功能,我检查了下一次冲压是否在 10 分钟内。如果是,则将其标记为排除。
显然,此解决方案并不完美,但可以让您到达需要的地方,并对错误有合理的容忍度。津贴的window可以扩大或缩小。
更新:您提供的新数据集超过了 10 分钟的限额。我把它提高到 20。同样,这里有一个错误容忍度。
我还调整了 InOut 查询以不使用任何以 TIMEATT = 1 作为开始时间的查询。这确保了 outpunches 永远不会作为开始时间进入数据集。
最后,我在输出查询中又添加了一个条件,以确保开始时间与请求的报告日期一致。
IF OBJECT_ID('tempdb.dbo.#temptable', 'U') IS NOT NULL
DROP TABLE #temptable;
CREATE TABLE #temptable ( [Company] nvarchar(60), [ID] int, [NAME] nvarchar(130), [TIMEATT] int, [Time_CST] datetime )
INSERT INTO #temptable VALUES
( N'Company Ltd.', 11111, N'Done, Jane', 1, N'2019-04-28T18:00:27' ),
( N'Company Ltd.', 11111, N'Done, Jane', 1, N'2019-04-28T18:00:28' ), --Sometimes people tap their card twice
( N'Company Ltd.', 11111, N'Done, Jane', 2, N'2019-04-29T06:00:55' ),
( N'Company Ltd.', 11111, N'Done, Jane', 1, N'2019-04-29T06:01:55' ),
( N'Company Ltd.', 11111, N'Done, Jane', 2, N'2019-04-29T06:04:55' ),
( N'Company Ltd.', 11111, N'Done, Jane', 1, N'2019-04-29T18:00:27' ),
( N'Company Ltd.', 11111, N'Done, Jane', 2, N'2019-04-30T06:13:55' ),
( N'Company Ltd.', 22222, N'Do, Jone', 1, N'2019-04-29T06:20:17' ),
( N'Company Ltd.', 22222, N'Do, Jone', 2, N'2019-04-29T06:47:12' ),
( N'Company Ltd.', 22222, N'Do, Jone', 1, N'2019-04-29T10:33:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 2, N'2019-04-29T18:05:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 1, N'2019-04-29T18:06:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 2, N'2019-04-29T18:09:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 1, N'2019-04-30T06:05:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 2, N'2019-04-30T16:05:33' )
-- Test table
-- 1 is entry and 2 is exit. Sometimes people double swipe their cards which results in two 1 entries.
select * from #temptable as T
--Report start
set deadlock_priority low;
declare @shift varchar(10) = 'night'; --Option to switch between day and night
declare @reportdate datetime = '2019-04-29'; --Date to be ran
declare @starttime datetime;
declare @endtime datetime;
select @starttime = (case
when @shift = 'day' then
convert(datetime, @reportdate) + cast('04:00:00.000' as datetime)
when @shift = 'night' then
convert(datetime, @reportdate) + cast('16:00:00.000' as datetime)
end
);
select @endtime = (case
when @shift = 'day' then
convert(datetime, @reportdate) + cast('23:59:59.000' as datetime)
when @shift = 'night' then
convert(datetime, dateadd(d, 1, @reportdate)) + cast('11:59:59.000' as datetime)
end
);
WITH NoDoubles AS
(
SELECT
Company
, [NAME]
, ID
, TIMEATT
, Time_CST
, CASE
WHEN LEAD(TIMEATT, 1, 0) OVER (PARTITION BY NAME ORDER BY Time_CST) = TIMEATT THEN 1
/* Allow for 10 minute grace period for swipes to be excluded */
WHEN LEAD(Time_CST, 1, 0) OVER (PARTITION BY NAME ORDER BY Time_CST) = '1900-01-01 00:00:00.000' THEN 0
WHEN LEAD(Time_CST, 1, 0) OVER (PARTITION BY NAME ORDER BY Time_CST) <= DATEADD(MINUTE, 10, Time_CST) THEN 1
ELSE 0
END
AS Exclude
FROM
#temptable
)
, InOut AS
(
SELECT
Company
, [NAME]
, ID AS EmpID
, IIF(TIMEATT = 1, Time_CST, NULL) AS startTime
, LEAD(Time_CST, 1, NULL) OVER (PARTITION BY NAME ORDER BY Time_CST) AS endTime
, TIMEATT
, Time_CST
FROM
NoDoubles
WHERE
Exclude = 0
)
SELECT
Company
, [NAME]
, EmpID
, startTime
, endTime
, SUM(DATEDIFF(SECOND, startTime, endTime) / 3600.0) AS HrsWorked
FROM
InOut
WHERE
CAST(startTime AS DATE) = @reportdate
AND startTime >= @starttime
AND endTime <= @endtime
GROUP BY
Company
, [NAME]
, EmpID
, startTime
, endTime
ORDER BY
Company
, [NAME]
, startTime;
DROP TABLE #temptable
所以 Chris 的回答给了我一个很好的工作格式。我正在查看是否有人在凌晨 4 点到中午 12 点之间进场,而在中午 12 点到晚上 7 点之间出场将被视为白班,其他人将被视为夜班。
set deadlock_priority low;
declare @shift varchar(10) = 'day' --Option to switch between day and night
declare @reportdate datetime = '2019-04-29' --Date to be ran
declare @starttime datetime
declare @endtime datetime
select @starttime = (case
when @shift = 'day' then
convert(datetime, @reportdate) + cast('04:00:00.000' as datetime)
when @shift = 'night' then
convert(datetime, @reportdate) + cast('16:00:00.000' as datetime)
end
)
select @endtime = (case
when @shift = 'day' then
convert(datetime, @reportdate) + cast('23:59:59.000' as datetime)
when @shift = 'night' then
convert(datetime, dateadd(d, 1, @reportdate)) + cast('11:59:59.000' as datetime)
end
)
;with NoDoubles
as (select Company
, NAME
, ID
, TIMEATT
, Time_CST
, case
when lead(TIMEATT, 1, 0) over (partition by NAME order by Time_CST) = TIMEATT then
1
/* Allow for 10 minute grace period for swipes to be excluded */
when lead(Time_CST, 1, 0) over (partition by NAME order by Time_CST) = '1900-01-01 00:00:00.000' then
0
when lead(Time_CST, 1, 0) over (partition by NAME order by Time_CST) <= dateadd(minute, 1, Time_CST) then
1
else
0
end as Exclude
from temptable)
, DayShiftEmpIds
as (select distinct
(case
when count(entertimes.ID) > 0 then
entertimes.ID
end
) as id
, 'day' as shift
--,case when count(entertimes.id)>0 then 'day' else 'night' end as [shift]
from temptable entertimes
, temptable exittimes
where entertimes.ID = exittimes.ID
and ((
(
entertimes.Time_CST >= @reportdate + cast('04:00:00' as datetime)
and entertimes.Time_CST <= @reportdate + cast('11:59:00' as datetime)
and entertimes.TIMEATT = 1
)
and
(
exittimes.Time_CST >= @reportdate + cast('12:00:00' as datetime)
and exittimes.Time_CST <= @reportdate + cast('19:59:00' as datetime)
and exittimes.TIMEATT = 2
)
)
)
group by entertimes.ID)
, NightShiftEmpIds
as (select distinct
ID
, 'night' as shift
from temptable as VCCIOT
where not exists
(
select id from DayShiftEmpIds where DayShiftEmpIds.ID = VCCIOT.ID
))
, AllEmpIdsWithShift
as (select *
from
(
select id
, shift
from DayShiftEmpIds
union
select ID
, shift
from NightShiftEmpIds
) as alldata
where alldata.shift = @shift)
, InOut
as (select Company
, NAME
, NoDoubles.ID as ID
, Time_CST as startTime
, lead(Time_CST, 1, null) over (partition by NAME order by Time_CST) as endTime
, TIMEATT
, Time_CST
from NoDoubles
inner join AllEmpIdsWithShift
on AllEmpIdsWithShift.id = NoDoubles.ID
where Exclude = 0)
select Company
, NAME
, ID
, startTime
, endTime
, sum(datediff(second, startTime, endTime) / 3600.0) as HrsWorked
from InOut
where TIMEATT = 1 -- filter so left column is always entry time.
and startTime >= @starttime
and endTime <= @endtime
group by Company
, NAME
, ID
, startTime
, endTime
order by Company
, NAME
, startTime;
目前,报告使用预定义的时间。但有时员工会超时工作,他们会偷偷进入下一个班次报告。如何修改报告查询以查看过去的登录时间以避免这种情况?在TIMEATT
列中,1
是入口,2
是出口。浅蓝色突出显示正确的条目,黄色表示错误的条目。
29 日的白班报告有“完成,简的”夜班入职时间
29 号的夜班报告有白班的“Do,Jone's”进入时间
下面的查询创建了一个临时文件 table,其中的数据与屏幕截图中的数据相同。
CREATE TABLE #temptable ( [Company] nvarchar(60), [ID] int, [NAME] nvarchar(130), [TIMEATT] int, [Time_CST] datetime )
INSERT INTO #temptable
values
( N'Company Ltd.', 11111, N'Done, Jane', 1, N'2019-04-28T18:00:27' ),
( N'Company Ltd.', 11111, N'Done, Jane', 1, N'2019-04-28T18:00:28' ), --Sometimes people tap their card twice
( N'Company Ltd.', 11111, N'Done, Jane', 2, N'2019-04-29T06:00:55' ),
( N'Company Ltd.', 11111, N'Done, Jane', 1, N'2019-04-29T06:01:55' ),
( N'Company Ltd.', 11111, N'Done, Jane', 2, N'2019-04-29T06:04:55' ),
( N'Company Ltd.', 11111, N'Done, Jane', 1, N'2019-04-29T18:00:27' ),
( N'Company Ltd.', 11111, N'Done, Jane', 2, N'2019-04-30T06:13:55' ),
( N'Company Ltd.', 22222, N'Do, Jone', 1, N'2019-04-29T06:20:17' ),
( N'Company Ltd.', 22222, N'Do, Jone', 2, N'2019-04-29T06:47:12' ),
( N'Company Ltd.', 22222, N'Do, Jone', 1, N'2019-04-29T10:33:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 2, N'2019-04-29T18:05:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 1, N'2019-04-29T18:06:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 2, N'2019-04-29T18:09:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 1, N'2019-04-30T06:05:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 2, N'2019-04-30T16:05:33' )
-- Test table
-- 1 is entry and 2 is exit. Sometimes people double swipe their cards which results in two 1 entries.
select * from #temptable as T
--Report start
set deadlock_priority low;
declare @shift varchar(10) = 'night'; --Option to switch between day and night
declare @reportdate datetime = '2019-04-29'; --Date to be ran
declare @starttime datetime;
declare @endtime datetime;
select @starttime = (case
when @shift = 'day' then
convert(datetime, @reportdate) + cast('04:00:00.000' as datetime)
when @shift = 'night' then
convert(datetime, @reportdate) + cast('16:00:00.000' as datetime)
end
);
select @endtime = (case
when @shift = 'day' then
convert(datetime, @reportdate) + cast('23:59:59.000' as datetime)
when @shift = 'night' then
convert(datetime, dateadd(d, 1, @reportdate)) + cast('11:59:59.000' as datetime)
end
);
select Company
, NAME
, EmpID
, startTime
, endTime
, sum(datediff(second, startTime, endTime) / 3600.0) as HrsWorked
from
( -- sub query to get matching exit time for each entry if it exists
select Company
, NAME
, ID as EmpID
, Time_CST as startTime
, lead(Time_CST, 1, null) over (partition by NAME order by Time_CST) as endTime
, TIMEATT
, Time_CST
from
( -- subquery to exclude duplicate records
select *
from
(
select *
from
( -- subquery to identify records to ignore
select Company
, NAME
, ID
, TIMEATT
, Time_CST
, case lead(TIMEATT, 1, 0) over (partition by NAME order by Time_CST)
when TIMEATT then
1
else
0
end as Exclude
from #temptable
) a
where Exclude = 0
) t
) n
) z
where TIMEATT = 1 -- filter so left column is always entry time.
and startTime >= @starttime
and endTime <= @endtime
--and Company in (@contractornames)
group by z.Company
, z.NAME
, z.EmpID
, z.startTime
, z.endTime
order by Company
, NAME
, startTime
--DROP TABLE #temptable
首先,我将您的查询更改为使用 CTE 而不是 3 级子查询。使其更易于阅读。
为了识别错误的打孔,我在您的查询中扩展了 CASE 语句,该语句识别重复的打孔并将它们标记为排除。使用 LEAD 功能,我检查了下一次冲压是否在 10 分钟内。如果是,则将其标记为排除。
显然,此解决方案并不完美,但可以让您到达需要的地方,并对错误有合理的容忍度。津贴的window可以扩大或缩小。
更新:您提供的新数据集超过了 10 分钟的限额。我把它提高到 20。同样,这里有一个错误容忍度。
我还调整了 InOut 查询以不使用任何以 TIMEATT = 1 作为开始时间的查询。这确保了 outpunches 永远不会作为开始时间进入数据集。
最后,我在输出查询中又添加了一个条件,以确保开始时间与请求的报告日期一致。
IF OBJECT_ID('tempdb.dbo.#temptable', 'U') IS NOT NULL
DROP TABLE #temptable;
CREATE TABLE #temptable ( [Company] nvarchar(60), [ID] int, [NAME] nvarchar(130), [TIMEATT] int, [Time_CST] datetime )
INSERT INTO #temptable VALUES
( N'Company Ltd.', 11111, N'Done, Jane', 1, N'2019-04-28T18:00:27' ),
( N'Company Ltd.', 11111, N'Done, Jane', 1, N'2019-04-28T18:00:28' ), --Sometimes people tap their card twice
( N'Company Ltd.', 11111, N'Done, Jane', 2, N'2019-04-29T06:00:55' ),
( N'Company Ltd.', 11111, N'Done, Jane', 1, N'2019-04-29T06:01:55' ),
( N'Company Ltd.', 11111, N'Done, Jane', 2, N'2019-04-29T06:04:55' ),
( N'Company Ltd.', 11111, N'Done, Jane', 1, N'2019-04-29T18:00:27' ),
( N'Company Ltd.', 11111, N'Done, Jane', 2, N'2019-04-30T06:13:55' ),
( N'Company Ltd.', 22222, N'Do, Jone', 1, N'2019-04-29T06:20:17' ),
( N'Company Ltd.', 22222, N'Do, Jone', 2, N'2019-04-29T06:47:12' ),
( N'Company Ltd.', 22222, N'Do, Jone', 1, N'2019-04-29T10:33:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 2, N'2019-04-29T18:05:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 1, N'2019-04-29T18:06:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 2, N'2019-04-29T18:09:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 1, N'2019-04-30T06:05:33' ),
( N'Company Ltd.', 22222, N'Do, Jone', 2, N'2019-04-30T16:05:33' )
-- Test table
-- 1 is entry and 2 is exit. Sometimes people double swipe their cards which results in two 1 entries.
select * from #temptable as T
--Report start
set deadlock_priority low;
declare @shift varchar(10) = 'night'; --Option to switch between day and night
declare @reportdate datetime = '2019-04-29'; --Date to be ran
declare @starttime datetime;
declare @endtime datetime;
select @starttime = (case
when @shift = 'day' then
convert(datetime, @reportdate) + cast('04:00:00.000' as datetime)
when @shift = 'night' then
convert(datetime, @reportdate) + cast('16:00:00.000' as datetime)
end
);
select @endtime = (case
when @shift = 'day' then
convert(datetime, @reportdate) + cast('23:59:59.000' as datetime)
when @shift = 'night' then
convert(datetime, dateadd(d, 1, @reportdate)) + cast('11:59:59.000' as datetime)
end
);
WITH NoDoubles AS
(
SELECT
Company
, [NAME]
, ID
, TIMEATT
, Time_CST
, CASE
WHEN LEAD(TIMEATT, 1, 0) OVER (PARTITION BY NAME ORDER BY Time_CST) = TIMEATT THEN 1
/* Allow for 10 minute grace period for swipes to be excluded */
WHEN LEAD(Time_CST, 1, 0) OVER (PARTITION BY NAME ORDER BY Time_CST) = '1900-01-01 00:00:00.000' THEN 0
WHEN LEAD(Time_CST, 1, 0) OVER (PARTITION BY NAME ORDER BY Time_CST) <= DATEADD(MINUTE, 10, Time_CST) THEN 1
ELSE 0
END
AS Exclude
FROM
#temptable
)
, InOut AS
(
SELECT
Company
, [NAME]
, ID AS EmpID
, IIF(TIMEATT = 1, Time_CST, NULL) AS startTime
, LEAD(Time_CST, 1, NULL) OVER (PARTITION BY NAME ORDER BY Time_CST) AS endTime
, TIMEATT
, Time_CST
FROM
NoDoubles
WHERE
Exclude = 0
)
SELECT
Company
, [NAME]
, EmpID
, startTime
, endTime
, SUM(DATEDIFF(SECOND, startTime, endTime) / 3600.0) AS HrsWorked
FROM
InOut
WHERE
CAST(startTime AS DATE) = @reportdate
AND startTime >= @starttime
AND endTime <= @endtime
GROUP BY
Company
, [NAME]
, EmpID
, startTime
, endTime
ORDER BY
Company
, [NAME]
, startTime;
DROP TABLE #temptable
所以 Chris 的回答给了我一个很好的工作格式。我正在查看是否有人在凌晨 4 点到中午 12 点之间进场,而在中午 12 点到晚上 7 点之间出场将被视为白班,其他人将被视为夜班。
set deadlock_priority low;
declare @shift varchar(10) = 'day' --Option to switch between day and night
declare @reportdate datetime = '2019-04-29' --Date to be ran
declare @starttime datetime
declare @endtime datetime
select @starttime = (case
when @shift = 'day' then
convert(datetime, @reportdate) + cast('04:00:00.000' as datetime)
when @shift = 'night' then
convert(datetime, @reportdate) + cast('16:00:00.000' as datetime)
end
)
select @endtime = (case
when @shift = 'day' then
convert(datetime, @reportdate) + cast('23:59:59.000' as datetime)
when @shift = 'night' then
convert(datetime, dateadd(d, 1, @reportdate)) + cast('11:59:59.000' as datetime)
end
)
;with NoDoubles
as (select Company
, NAME
, ID
, TIMEATT
, Time_CST
, case
when lead(TIMEATT, 1, 0) over (partition by NAME order by Time_CST) = TIMEATT then
1
/* Allow for 10 minute grace period for swipes to be excluded */
when lead(Time_CST, 1, 0) over (partition by NAME order by Time_CST) = '1900-01-01 00:00:00.000' then
0
when lead(Time_CST, 1, 0) over (partition by NAME order by Time_CST) <= dateadd(minute, 1, Time_CST) then
1
else
0
end as Exclude
from temptable)
, DayShiftEmpIds
as (select distinct
(case
when count(entertimes.ID) > 0 then
entertimes.ID
end
) as id
, 'day' as shift
--,case when count(entertimes.id)>0 then 'day' else 'night' end as [shift]
from temptable entertimes
, temptable exittimes
where entertimes.ID = exittimes.ID
and ((
(
entertimes.Time_CST >= @reportdate + cast('04:00:00' as datetime)
and entertimes.Time_CST <= @reportdate + cast('11:59:00' as datetime)
and entertimes.TIMEATT = 1
)
and
(
exittimes.Time_CST >= @reportdate + cast('12:00:00' as datetime)
and exittimes.Time_CST <= @reportdate + cast('19:59:00' as datetime)
and exittimes.TIMEATT = 2
)
)
)
group by entertimes.ID)
, NightShiftEmpIds
as (select distinct
ID
, 'night' as shift
from temptable as VCCIOT
where not exists
(
select id from DayShiftEmpIds where DayShiftEmpIds.ID = VCCIOT.ID
))
, AllEmpIdsWithShift
as (select *
from
(
select id
, shift
from DayShiftEmpIds
union
select ID
, shift
from NightShiftEmpIds
) as alldata
where alldata.shift = @shift)
, InOut
as (select Company
, NAME
, NoDoubles.ID as ID
, Time_CST as startTime
, lead(Time_CST, 1, null) over (partition by NAME order by Time_CST) as endTime
, TIMEATT
, Time_CST
from NoDoubles
inner join AllEmpIdsWithShift
on AllEmpIdsWithShift.id = NoDoubles.ID
where Exclude = 0)
select Company
, NAME
, ID
, startTime
, endTime
, sum(datediff(second, startTime, endTime) / 3600.0) as HrsWorked
from InOut
where TIMEATT = 1 -- filter so left column is always entry time.
and startTime >= @starttime
and endTime <= @endtime
group by Company
, NAME
, ID
, startTime
, endTime
order by Company
, NAME
, startTime;