Vous êtes si doué pour le code. Je peux utiliser un meilleur SQL qui me dira le nombre de jours dans un mois que chaque employé a travaillé. Chaque employé peut entrer et sortir plusieurs fois par jour et travailler jusqu'à minuit. Si elles travaillent plus de minuit, ça compte comme 2 jours de travail. Si elles travaillaient après minuit et arrivaient plus tard le même jour et partaient avant minuit, ce temps aurait déjà été compté puisque c'était le même jour.Comptez le nombre de jours travaillés
Cela fonctionne mais est-il un moyen plus facile?
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
Si un employé donne un coup de poing à 23h00 le 15, travaille 26 heures (bénisse son coeur) et puis sort à 1 heure du matin le 17, le 16 ci-dessus manquera. – Brian
@Brian C'est vraiment marrant, merci pour le rire. Cet employé devrait reconsidérer sa ligne de travail. Mais sérieusement, je ne cherchais qu'à optimiser le code d'OP qui ne tiendrait pas non plus compte de cette situation. Je pourrais écrire quelque chose qui en rendrait compte si nécessaire, mais à moins que cette situation ne soit un souci, cela ne ferait que rendre le code beaucoup plus complexe qu'il ne devrait l'être. –
De rien :). Quand j'ai lu le code de l'OP pour la première fois, je pensais qu'il avait expliqué ce cas, mais après examen, je vois que vous avez raison - il ne l'a pas fait. Le code que vous avez présenté semble certainement correspondre à l'exemple de code de l'OP. – Brian