1
你们是如此善于打理代码。我可以使用更好的SQL来告诉我每个员工每月工作的天数。每个员工每天可以进出几次,并且可以在午夜之前工作。如果他们在午夜工作,则计为工作2天。如果他们在午夜时分工作并在当天晚些时候进入,并在下一个午夜之前离开,那么这段时间自同一天以来就已经被计算在内。计算工作天数
这有效,但有没有更简单的方法?
IF OBJECT_ID ('dbo.ZTable1', 'U') IS NOT NULL
DROP TABLE dbo.ZTable1;
GO
CREATE TABLE dbo.ZTable1 ([EmployeeId] Numeric (5,0), [TimeIn] datetime,
[TimeOut] datetime)
INSERT INTO dbo.ZTable1 ([EmployeeId],[TimeIn],[TimeOut]) SELECT 1,'2017-09-
13 12:19','2017-09-14 00:01'
INSERT INTO dbo.ZTable1 ([EmployeeId],[TimeIn],[TimeOut]) SELECT 1,'2017-09-
14 12:15','2017-09-15 00:01'
INSERT INTO dbo.ZTable1 ([EmployeeId],[TimeIn],[TimeOut]) SELECT 1,'2017-09-
15 12:35','2017-09-16 00:01'
INSERT INTO dbo.ZTable1 ([EmployeeId],[TimeIn],[TimeOut]) SELECT 1,'2017-09-
16 07:56','2017-09-16 10:31'
INSERT INTO dbo.ZTable1 ([EmployeeId],[TimeIn],[TimeOut]) SELECT 1,'2017-09-
16 11:56','2017-09-16 16:31'
INSERT INTO dbo.ZTable1 ([EmployeeId],[TimeIn],[TimeOut]) SELECT 2,'2017-09-
13 15:26','2017-09-14 00:00'
INSERT INTO dbo.ZTable1 ([EmployeeId],[TimeIn],[TimeOut]) SELECT 2,'2017-09-
14 15:29','2017-09-15 00:00'
INSERT INTO dbo.ZTable1 ([EmployeeId],[TimeIn],[TimeOut]) SELECT 2,'2017-09-
15 15:27','2017-09-16 00:01'
INSERT INTO dbo.ZTable1 ([EmployeeId],[TimeIn],[TimeOut]) SELECT 3,'2017-09-
13 15:25','2017-09-14 00:01'
INSERT INTO dbo.ZTable1 ([EmployeeId],[TimeIn],[TimeOut]) SELECT 3,'2017-09-
14 15:25','2017-09-15 00:00'
INSERT INTO dbo.ZTable1 ([EmployeeId],[TimeIn],[TimeOut]) SELECT 3,'2017-09-
15 15:26','2017-09-16 00:00'
INSERT INTO dbo.ZTable1 ([EmployeeId],[TimeIn],[TimeOut]) SELECT 3,'2017-09-
16 06:55','2017-09-16 15:27'
GO;
With Step1 as ( --< Build temp table of in punch days
Select [EmployeeId], DATEPART (DAY ,[TimeIn]) as WorkDay
from dbo.ZTable1
),
Step2 as ( --< Build temp table of out punch days
Select [EmployeeId], DATEPART (DAY ,[TimeOut]) as WorkDay
from dbo.ZTable1
),
Step3 as ( --< merges both in and put punch tables
Select
Case when s1.[EmployeeId] is NULL then s2.[EmployeeId] else s1.[EmployeeId] end as Employee,
case when s1.WorkDay is NULL then s2.WorkDay else s1.WorkDay end as WorkDate
from Step1 s1
full outer join Step2 s2 on s1.[EmployeeId] = s2.[EmployeeId] and s1.WorkDay = s2.WorkDay
),
Step4 as ( --< Organizes temp table
Select Distinct Employee, WorkDate
from Step3
group by Employee, WorkDate
)
Select Employee, Count (Employee) as NumDays
from Step4
Where Employee > 0
Group by Employee
Order by Employee
DROP TABLE dbo.ZTable1
Output (Result)
Employee NumDays
1 4
2 4
3 4
如果员工在下午11点打卡, 15日工作26小时(保佑他的心),然后在17日凌晨1点打出,上述将错过16日。 – Brian
@Brian这真的很有趣,谢谢你的笑声。该员工应该重新考虑他的工作。但严重的是,我只是旨在优化OP的代码,这也不能解释这种情况。如果有必要,我可以写一些能够解释它的东西,但除非这种情况是一个问题,否则它只会使代码比需要的复杂得多。 –
不客气:)。当我第一次阅读OP的代码时,我认为他已经解释了这个案例,但在审查时我发现你是对的 - 他没有。您提供的代码在功能上似乎与OP的示例代码相匹配。 – Brian