Gestione timbrature: Estrarre presenti in azienda

martedì 10 aprile 2012 - 17.17
Tag Elenco Tags  SQL Server 2008 R2  |  SQL Server 2008  |  SQL Server 2005  |  SQL Server 2000  |  SQL Server Express

gemepaso Profilo | Newbie

Ciao A tutti

su un DB SQL vengono registrati gli accessi di tutti i dipendenti dell'azienda in questa modo

N_TES UTENTE DATA ORA E/U
101 Pippo 30/03/2012 8:14:37 Entrata
101 Pippo 29/03/2012 19:22:37 Uscita
102 Caio 29/03/2012 12:16:27 Uscita
102 Caio 29/03/2012 8:18:08 Entrata
101 Pippo 29/03/2012 8:15:04 Entrata
103 Semppronio 29/03/2012 6:01:25 Uscita
103 Semppronio 28/03/2012 21:30:08 Entrata
101 Pippo 28/03/2012 17:43:46 Uscita
102 Caio 28/03/2012 14:00:43 Uscita
101 Pippo 28/03/2012 8:23:41 Entrata


Guardando semplicemente l'ultima tibrata di ogni dipendente (entrata o un uscita) devo estrarre un report che mi dica per ognuno se è presente o no in azienda.
Pensavo di creare una procedura, dove per ogni utente ricavo l'ultimo accesso. Essendo parecchie centinaia di dipendenti con un archivio dati che supera oramai le 400.000 righe, ho paura che questa possa risultare troppo lenta...

Magari potete consigliarmi una semplice query o altro....

Grazie
Marco


lbenaglia Profilo | Guru

>Guardando semplicemente l'ultima tibrata di ogni dipendente (entrata
>o un uscita) devo estrarre un report che mi dica per ognuno se
>è presente o no in azienda.

Ciao Marco,

Suppongo che il report servirà per fornirti la situazione puntuale in una certa data e ora di tutti i dipendenti che hanno timbrato dalla mezzanotte, corretto?
In questo caso potresti preparare una stored procedure che accetti in input la data e l'ora e ti fornisca un result set di tutti i dipendenti con una colonna bit che ti indichi se sono o meno in azienda.
Prova a dare un'occhiata al seguente esempio:

USE tempdb; CREATE TABLE dbo.Dipendenti( N_TES int NOT NULL, UTENTE varchar(10) NOT NULL, [DATA ORA] datetime NOT NULL, [E/U] varchar(10) NOT NULL ); INSERT dbo.Dipendenti VALUES(101, 'Pippo', '20120330 8:14:37', 'Entrata') , (101, 'Pippo', '20120329 19:22:37', 'Uscita') , (102, 'Caio', '20120329 12:16:27', 'Uscita') , (102, 'Caio', '20120329 8:18:08', 'Entrata') , (101, 'Pippo', '20120329 8:15:04', 'Entrata') , (103, 'Sempronio', '20120329 6:01:25', 'Uscita') , (103, 'Sempronio', '20120328 21:30:08', 'Entrata') , (101, 'Pippo', '20120328 17:43:46', 'Uscita') , (102, 'Caio', '20120328 14:00:43', 'Uscita') , (101, 'Pippo', '20120328 8:23:41', 'Entrata'); /* Soluzione per SQL Server 2005+ */ WITH CTE_GetKey(N_TES, [DATA ORA]) AS ( SELECT N_TES, MAX([DATA ORA]) FROM dbo.Dipendenti WHERE [DATA ORA] >= '20120328' AND [DATA ORA] < '20120329' GROUP BY N_TES ) SELECT D.N_TES , D.UTENTE , CASE [E/U] WHEN 'Entrata' THEN 1 ELSE 0 END 'In azienda' FROM dbo.Dipendenti AS D JOIN CTE_GetKey AS CTE ON D.N_TES = CTE.N_TES AND D.[DATA ORA] = CTE.[DATA ORA] ORDER BY N_TES; /* Soluzione per SQL Server 2012 */ SELECT DISTINCT N_TES , UTENTE , CASE FIRST_VALUE([E/U]) OVER (PARTITION BY N_TES ORDER BY [DATA ORA] DESC) WHEN 'Entrata' THEN 1 ELSE 0 END 'In azienda' FROM dbo.Dipendenti WHERE [DATA ORA] >= '20120328' AND [DATA ORA] < '20120329' ORDER BY N_TES; /* Output: N_TES UTENTE In azienda ----------- ---------- ----------- 101 Pippo 0 102 Caio 0 103 Sempronio 1 (3 row(s) affected) */ GO /* Supponendo di lavorare con SQL Server 2012... */ CREATE PROCEDURE dbo.up_GetEmployees(@Date AS datetime) AS SELECT DISTINCT N_TES , UTENTE , CASE FIRST_VALUE([E/U]) OVER (PARTITION BY N_TES ORDER BY [DATA ORA] DESC) WHEN 'Entrata' THEN 1 ELSE 0 END 'In azienda' FROM dbo.Dipendenti WHERE [DATA ORA] BETWEEN CAST(@Date AS date) AND @Date ORDER BY N_TES; GO EXEC dbo.up_GetEmployees '20120328 17:43:45'; /* Output: N_TES UTENTE In azienda ----------- ---------- ----------- 101 Pippo 1 102 Caio 0 (2 row(s) affected) */ EXEC dbo.up_GetEmployees '20120328 17:43:46'; /* Output: N_TES UTENTE In azienda ----------- ---------- ----------- 101 Pippo 0 102 Caio 0 (2 row(s) affected) */ EXEC dbo.up_GetEmployees '20120328 21:30:08'; /* Output: N_TES UTENTE In azienda ----------- ---------- ----------- 101 Pippo 0 102 Caio 0 103 Sempronio 1 (3 row(s) affected) */ EXEC dbo.up_GetEmployees '20120329 8:00:00'; /* Output: N_TES UTENTE In azienda ----------- ---------- ----------- 103 Sempronio 0 (1 row(s) affected) */ EXEC dbo.up_GetEmployees '20120329 19:30:00'; /* Output: N_TES UTENTE In azienda ----------- ---------- ----------- 101 Pippo 0 102 Caio 0 103 Sempronio 0 (3 row(s) affected) */ DROP PROCEDURE dbo.up_GetEmployees; DROP TABLE dbo.Dipendenti;

Eventualmente adattalo alle tue esigenze

>Grazie
Prego.

Ciao!
--
Lorenzo Benaglia
http://blogs.dotnethell.it/lorenzo/

gemepaso Profilo | Newbie

Senza parole...

PERFETTO (Ho adottato la soluzione x SQL 2005)
Grazie
Marco

ratum99 Profilo | Junior Member

>Senza parole...
>
>PERFETTO (Ho adottato la soluzione x SQL 2005)
>Grazie
>Marco
>

Ciao,

se vuoi ci sono vari programmi, anche web (quindi visualizzabili da varie postazioni), che ti fanno già la visualizzazione che ti serve.
Volendo anche gestendoti i dipendenti in pausa, o i dipendenti assenti con a fianco la motivazione dell'assenza ecc..

un programma di questo tipo lo puoi trovare qui http://www.folli.it/index.php/rilevazione-presenze/software/software-rilevazione-presenze-info-web.html
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5