Principale utente con più risposte
Query

Domanda
-
Ciao a tutti, la mia query sembra bne formulata logicamente ma non riesco a capire perchè non va .
Allora ho la tabella principale che chiamo miaTabella fatta dai seguenti campiID Int PK,
IDDipendente Int FK,
Orarioin pratica nella miatabella vado a registrare le timbrature dei dipendenti di un'azienda.
Adesso devo produrre un resultset dove riepilogo i risultati della tabella A ma aggiungendo una colonna PrimaTimbratura che mi fa vedere la prima timbratura assoluta per quel particolare dipendente
Progetto la query in questo modo ma non va come dico io
Select A.ID, A.IDDipendente, A.Orario, B.PrimaTimbratura From miaTabella As A Left Join ( Select IDDipendente, Orario From miaTabella Where IDDipendente In (Select distinct IDDipendente From miaTabella) ) As B On A.IDDipendente = B.IDDIpendente
Risposte
-
salve,
no, devi scusarmi tu... mi sono lasciato prendere dalla foga e nella stanchezza non ho visto la soluzione piu' semplice... ti basta effettuare un raggruppamento per IdDipendente di MIN(Orario)... il risultato parziale lo metti in join con la tabella originale ed hai quanto richiesto... per tua comodita' e leggibilita' incapsula la subquery in una common table expression che andrai ad utilizzare similarmente a
SET NOCOUNT ON; USE tempdb; GO CREATE TABLE dbo.t ( Id int NOT NULL IDENTITY, IdDipendente int, Orario datetime ); GO INSERT INTO dbo.t VALUES (1, '20120101 08:00'), (2, '20120101 08:10'), (1, '20120102 09:00'), (2, '20120102 10:00'), (1, '20120103 08:00'), (2, '20120103 18:00'); GO WITH cte AS ( SELECT t.IdDipendente, MIN(t.Orario) AS [1^ timbratura assoluta] FROM dbo.t t GROUP BY t.IdDipendente ) SELECT t.Id, t.IdDipendente, t.Orario, c.[1^ timbratura assoluta] FROM dbo.t t JOIN cte c ON c.IdDipendente = t.IdDipendente ORDER BY t.IdDipendente, t.Orario; GO DROP TABLE dbo.t;
saluti e scusa ancora
http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/
- Proposto come risposta Enzo Di Costanzo giovedì 14 giugno 2012 20:11
- Contrassegnato come risposta Fabrizio GiammariniMVP, Moderator lunedì 16 luglio 2012 16:47
Tutte le risposte
-
salve,
non so se ho ben compreso la richiesta... ad ogni modo...
SET NOCOUNT ON; USE tempdb; GO CREATE TABLE dbo.t ( Id int NOT NULL IDENTITY, IdDipendente int, Orario datetime ); GO INSERT INTO dbo.t VALUES (1, '20120101 08:00'), (2, '20120101 08:10'), (1, '20120102 09:00'), (2, '20120102 10:00'), (1, '20120103 08:00'), (2, '20120103 18:00'); GO PRINT 'SQL Server 2012, estensione FIRST_VALUE in window aggregates'; SELECT t.Id, t.IdDipendente, t.Orario , FIRST_VALUE(t.Orario) OVER (PARTITION BY t.IdDipendente ORDER BY t.IdDipendente, t.Orario) AS [1^ timbratura assoluta] FROM dbo.t t ORDER BY t.IdDipendente, t.Orario; SELECT t.Id, t.IdDipendente, t.Orario , MIN(t.Orario) OVER (PARTITION BY t.IdDipendente) AS [1^ timbratura assoluta] FROM dbo.t t ORDER BY t.IdDipendente, t.Orario; GO WITH cte AS ( SELECT t.IdDipendente, t.Orario, ROW_NUMBER() OVER (PARTITION BY t.IdDipendente ORDER BY t.IdDipendente, t.Orario) AS [r] FROM dbo.t t ) SELECT t.Id, t.IdDipendente, t.Orario, c.Orario AS [1^ timbratura assoluta] FROM dbo.t t LEFT JOIN cte c ON c.IdDipendente = t.IdDipendente WHERE c.[r] = 1 ORDER BY t.IdDipendente, t.Orario; GO DROP TABLE dbo.t; --<------ SQL Server 2012, estensione FIRST_VALUE in window aggregates Id IdDipendente Orario 1^ timbratura assoluta ----------- ------------ ----------------------- ----------------------- 1 1 2012-01-01 08:00:00.000 2012-01-01 08:00:00.000 3 1 2012-01-02 09:00:00.000 2012-01-01 08:00:00.000 5 1 2012-01-03 08:00:00.000 2012-01-01 08:00:00.000 2 2 2012-01-01 08:10:00.000 2012-01-01 08:10:00.000 4 2 2012-01-02 10:00:00.000 2012-01-01 08:10:00.000 6 2 2012-01-03 18:00:00.000 2012-01-01 08:10:00.000 Id IdDipendente Orario 1^ timbratura assoluta ----------- ------------ ----------------------- ----------------------- 1 1 2012-01-01 08:00:00.000 2012-01-01 08:00:00.000 3 1 2012-01-02 09:00:00.000 2012-01-01 08:00:00.000 5 1 2012-01-03 08:00:00.000 2012-01-01 08:00:00.000 2 2 2012-01-01 08:10:00.000 2012-01-01 08:10:00.000 4 2 2012-01-02 10:00:00.000 2012-01-01 08:10:00.000 6 2 2012-01-03 18:00:00.000 2012-01-01 08:10:00.000 Id IdDipendente Orario 1^ timbratura assoluta ----------- ------------ ----------------------- ----------------------- 1 1 2012-01-01 08:00:00.000 2012-01-01 08:00:00.000 3 1 2012-01-02 09:00:00.000 2012-01-01 08:00:00.000 5 1 2012-01-03 08:00:00.000 2012-01-01 08:00:00.000 2 2 2012-01-01 08:10:00.000 2012-01-01 08:10:00.000 4 2 2012-01-02 10:00:00.000 2012-01-01 08:10:00.000 6 2 2012-01-03 18:00:00.000 2012-01-01 08:10:00.000
la prima soluzione e' basata sulle nuove funzionalita' di analytical windowing aggregation esposte da SQL Server 2012, dove FIRST_VALUE(colonna) ritorna il valore desiderato, la prima timbratura per partizionamento di dipendente ordinata per Orario... stessa "limitazione" per la seconda, che utilizza l'estensione OVER della funzione MIN
la terza e' invece basata sempre su funzionalita' di windowing pero' disponibili gia' a partire da SQL Server 2005, dove con ROW_NUMBER() ottengo un ordinamento persistito all'interno del medesimo partizionamento per IdDipendente ordinato per Orario in una common table expression ausiliaria... tale CTE viene poi messa in join con la tabella originale per associare ad ogni riga originale la sola riga della CTE del dipendente in oggetto che abbia ROW_NUMBER = 1, cioe' la prima riga stessa...
saluti
http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/
- Modificato Andrea MontanariModerator mercoledì 13 giugno 2012 00:33
-
Perdona la mia ignoranza, delle cose non le conosco proprio, non ci sarei mai potuto arrivare.
Ma allora con t-sql classico non posso risolvere questo problema, giusto ?
Comunque, la prima soluzione non riesco a farla partire in quanto utilizzo sql server 2008 r2- Modificato kio2008 mercoledì 13 giugno 2012 07:00
-
salve,
no, devi scusarmi tu... mi sono lasciato prendere dalla foga e nella stanchezza non ho visto la soluzione piu' semplice... ti basta effettuare un raggruppamento per IdDipendente di MIN(Orario)... il risultato parziale lo metti in join con la tabella originale ed hai quanto richiesto... per tua comodita' e leggibilita' incapsula la subquery in una common table expression che andrai ad utilizzare similarmente a
SET NOCOUNT ON; USE tempdb; GO CREATE TABLE dbo.t ( Id int NOT NULL IDENTITY, IdDipendente int, Orario datetime ); GO INSERT INTO dbo.t VALUES (1, '20120101 08:00'), (2, '20120101 08:10'), (1, '20120102 09:00'), (2, '20120102 10:00'), (1, '20120103 08:00'), (2, '20120103 18:00'); GO WITH cte AS ( SELECT t.IdDipendente, MIN(t.Orario) AS [1^ timbratura assoluta] FROM dbo.t t GROUP BY t.IdDipendente ) SELECT t.Id, t.IdDipendente, t.Orario, c.[1^ timbratura assoluta] FROM dbo.t t JOIN cte c ON c.IdDipendente = t.IdDipendente ORDER BY t.IdDipendente, t.Orario; GO DROP TABLE dbo.t;
saluti e scusa ancora
http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/
- Proposto come risposta Enzo Di Costanzo giovedì 14 giugno 2012 20:11
- Contrassegnato come risposta Fabrizio GiammariniMVP, Moderator lunedì 16 luglio 2012 16:47