>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/