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