È possibile utilizzare una sottoselezione o CTE per ottenere i dati ordinati per dipendente e utilizzarli come tabella dati principale. Qualcosa di simile (adattarlo se necessario) a questo:
;with ordered as (
select
emp_reader_id as empId,
CONVERT(DATE, dt) as Punch,
Row_number()
OVER (PARTITION BY emp_reader_id ORDER BY CONVERT(DATE, dt) ASC) as OrderedPunch
from trnevents
)
SELECT
entered.empId,
entered.Punch as PunchIn,
exited.Punch as PunchOut
from
ordered as entered
left join ordered as exited on
entered.empId = exited.empId
and entered.OrderedPunch + 1 = exited.OrderedPunch
Spiegazione:Il CTE "ordinato" mostra le entrate/uscite dei dipendenti ordinate per data. Il ROW_NUMBER
viene reimpostato per ogni dipendente (presumo che emp_reader_id contenga l'ID dipendente) a causa di PARTITION BY
.
Una volta ottenuto il contatore per ogni dipendente, unisco ogni pugno per ogni dipendente (prima condizione nel join sinistro) con il pugno successivo per quel dipendente (seconda condizione nel join sinistro). In questo modo posso mostrare la colonna di entrata e l'uscita (il prossimo pugno).
Dopo aver ottenuto le colonne in entrata e in uscita nei tuoi dati, potresti voler escludere alcuni dati (le righe dispari di ciascun dipendente sono le righe che vorresti) aggiungendo WHERE entered.OrderedPunch %2 = 1