2017-09-05 2 views
2

Je souhaite diviser les données de temps d'un employé en plusieurs lignes en fonction de leur heure d'arrivée. Pour cet exemple, si elles arrivent avant 7 heures, tout ce qui précède sera séparé en une nouvelle ligne des données et tout 7 heures et après est l'autre rangée. Voici un exemple de données avec l'ensemble de résultats souhaité. Ceci est pour aider à calculer les heures supplémentaires. Si elles apparaissent avant leur quart de travail fixe alors que le temps est OT payerDivision des données de temps en plusieurs lignes

Create Table TimeData(
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [EmployeeID] int NULL, 
    [Date] date NULL, 
    [TimeIn] time NULL, 
    [TimeOut] time Null, 
) 

Insert Into TimeData (EmployeeID,Date,Timein,TimeOut) 
Values (100,'9/5/2017','06:00','15:00') 

jeux de résultats

(100, '9/5/2017', '06h00', '7:00')

(100, '9/5/2017', '07h00', '15:00')

l'Union Toutes les suggestions ci-dessous m'a orienté dans la bonne direction et je suis venu avec cet ensemble de requête pour créer un nouvel enregistrement de temps pour les employés qui ont frappé avant 07h00 et ensuite mettre à jour l'original.

BEGIN 
INSERT INTO Timedata(EmployeeID,Date,TimeIn,TimeOut) 
SELECT 
    [EmployeeID], 
    [Date], 
    [TimeIn] AS [Time], '7:00' 
FROM 
    TimeData 
WHERE 
    [TimeIn] < '07:00:00' 
END 

BEGIN 
UPDATE TimeData Set TimeIn = '07:00' WHERE TimeIN < '07:00' AND TimeOut <> '7:00' 
END 
+0

Mais pourquoi? Quelle est la raison commerciale derrière tout cela? Sont ces changements? Pas mon DV BTW. – scsimon

+0

Le DV est pour montrer absolument aucun effort de recherche. –

+0

Ceci est pour aider à calculer les heures supplémentaires. S'ils se présentent avant leur quart de travail, ce temps est payé par OT. La procédure stockée réelle est beaucoup plus complexe. Il y aura plusieurs entrées de temps pour un jour et le total des heures sera calculé, mais j'ai juste besoin d'un brain storming collectif sur la façon de dégager ce tumle. Je ne pense pas que ça mérite un DV mais si ça devient DV et que je reçois toujours de l'aide de la communauté, c'est quand même très apprécié – BrianMichaels

Répondre

2

Utilisez une requête UNION:

SELECT EmployeeID, Date, TimeIn, '07:00' as TimeOut FROM timedata WHERE Timein < '07:00' 
UNION ALL 
SELECT EmployeeID, Date, '07:00', TimeOut FROM timedata WHERE TimeOut > '07:00'; 

d'abord sélectionner toutes les lignes où la TimeIn est inférieure à 7 heures, et le réglage de la TimeOut appropriée. Ensuite, sélectionnez tous les enregistrements où TimeOut est supérieur à 7 heures et définissez le TimeIn approprié.

+0

Mais qu'en est-il s'il y a un changement qui se produit entièrement avant ou après 7? –

+1

Et s'ils travaillent un quart de travail qui commence avant minuit? Il y a une tonne de quoi si OP pour résoudre pour ici. Je pense que UNION ALL est le grand Aha! pour OP. – JNevill

+0

oui c'est merci. Je vais commencer à jouer avec cette idée et poster mes résultats finaux. – BrianMichaels

1

Une méthode rapide via une croix Appliquer

Select A.ID 
     ,A.EmployeeID 
     ,A.Date 
     ,B.* 
From TimeData A 
Cross Apply (values (TimeIn,case when TimeIn<'07:00' then cast('07:00' as time) else TimeOut end) 
        ,(case when TimeIn<'07:00' then cast('07:00' as time) else null end 
         ,case when TimeIn<'07:00' then TimeOut else null end) 
       ) B(TimeIn,TimeOut) 
Where B.TimeIn <> B.TimeOut 

retour - Ajout d'une fiche de 7-3

enter image description here

1

UTILISATION UNION ALL et écrire une requête qui obtient haut la avant 7 partie, et une requête de fond qui obtient la partie après 7.

Puis simplement COMMANDER PAR EmployeeID, TimeIn.

1

Je ne suis pas sûr de comprendre votre question, est-ce quelque chose de similaire à ce que vous cherchez?

SELECT 
    TimeData.EmployeeID, 
    [Date], 
    TimeData.[TimeIn] AS [Time] 
FROM 
    TimeData 
WHERE 
    [TimeIn] < '07:00:00' 
UNION 
SELECT 
    TimeData.EmployeeID, 
    [Date], 
    TimeData.TimeOut As [Time] 
FROM 
    TimeData 
ORDER BY 
    EmployeeID, 
    [Date], 
    [Time] 
1

Nous pouvons utiliser une méthode pilotée par table pour la décision de la répartition des heures de travail.

SELECT 
    EmployeeID, 
    Date, 
    TimeIn = CASE WHEN TD.TimeIn > splitBegin THEN TimeIn ELSE splitBegin END, 
    TimeOut = CASE WHEN TD.TimeOut < splitEnd THEN TimeOut ELSE splitEnd END 
from TimeData TD 
INNER JOIN (VALUES('00:00','07:00'),('07:00','23:59')) T(splitBegin,splitEnd) 
    ON (TD.TimeIN > T.splitBegin AND TD.TimeIN < T.splitEnd) 
    OR (TD.TimeOut > T.splitBegin AND TD.TimeOut < T.splitEnd)