【发布时间】:2019-09-20 07:13:04
【问题描述】:
目前,报告使用预定义的时间。但有时员工超时工作,他们潜入下一个班次报告。如何修改报告查询以查看过去的登录时间以避免这种情况?在TIMEATT 列中,1 是入口,2 是出口。浅蓝色突出显示正确的条目,黄色表示不正确的条目。
29 日的夜班报告中包含“Do,Jone's”从白班开始的进入时间
下面的查询创建了一个临时表,其中的数据与屏幕截图中的数据相同。
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
【问题讨论】:
-
我尝试创建一个 SQL 小提琴,但由于某种原因,我收到一条错误消息,指出需要声明 @shift。 sqlfiddle.com/#!18/053107/1
-
在执行您的代码时收到错误消息数据类型 date 和 datetime 在 add 运算符中不兼容。
-
对不起,我错误地将问题标记为 2012。但是服务器版本是 MS SQL Server 2014。您使用的是什么版本?
-
使用 SSMS 18 针对 2012 年和 2016 年进行了测试。
-
sqlfiddle.com/#!18/2e4e1/1 我确实设法让它在这里运行
标签: sql tsql sql-server-2014 ssrs-2012