皆さんはコードをすっきりと作成することができます。私は各従業員が働いた月の日数を教えてくれるより良いSQLを使うことができます。各従業員は1日に何度もパンチイン/アウトしたり、深夜に働くことができます。彼らが真夜中に働くならば、それは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