none
Query RRS feed

  • 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 campi

    ID Int PK,
    IDDipendente Int FK,
    Orario

    in 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
    

    martedì 12 giugno 2012 21:54

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/

    mercoledì 13 giugno 2012 20:08
    Moderatore

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/


    mercoledì 13 giugno 2012 00:06
    Moderatore
  • 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
    mercoledì 13 giugno 2012 06:54
  • 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/

    mercoledì 13 giugno 2012 20:08
    Moderatore