Query confronto dati di 2 Esercizi

di il
2 risposte

Query confronto dati di 2 Esercizi

Salve a tutti, ho il seguente codice che mi raggruppa q.ta e fatturato per articolo in un Esercizio:

SELECT FRighe.FR_CodArt, FRighe.FR_Desc, 
			FRighe.FR_Um, Sum([FRighe].[FR_Qta]*[Causali].[cau_Mov]*-1) AS QTA, 
			Sum(CASE FRighe.FR_Tipo WHEN 14 THEN FRighe.FR_ImportoRiga*-1 ELSE FRighe.FR_ImportoRiga END) AS Fatt,
			ROW_NUMBER() OVER(ORDER BY FRighe.FR_CodArt) as Riga
			FROM Fatture INNER JOIN (FRighe INNER JOIN Causali ON FRighe.FR_Tipo = Causali.cau_ID) ON (Fatture.F_Tipo = FRighe.FR_Tipo) AND (Fatture.F_Ese = FRighe.FR_Ese) AND (Fatture.F_Num = FRighe.FR_Num)
			WHERE (((FRighe.FR_Ese)=@Ese) AND ((Causali.cau_Mov)<>0) AND ((Causali.cau_Dest)=0) AND ((Fatture.F_Cli)=@Cli))
			GROUP BY FRighe.FR_CodArt, FRighe.FR_Desc, FRighe.FR_Um	ORDER BY FRighe.FR_CodArt
Mi servirebbe aggiungere due colonne dopo l'alias Riga con la Qta e il Fatt dell'anno precedente raggruppati ovviamente per articolo.
Sapreste darmi una dritta?

2 Risposte

  • Re: Query confronto dati di 2 Esercizi

    Salve,
    puoi innanzitutto filtrare la selezione originale includendo, oltre all'anno corrente passato come parametro, anche l'anno desiderato, e, nella proiezione vera e propria, gia' raggruppata come gia' fatto, effettuare una "rotazione" orizzontale su colonna con un'ulteriore espressione di CASE WHEN anno = anno_Corrente o anno_Precedente...

    trivialmente, qui semplificato in
    
    SET NOCOUNT ON;
    USE tempdb;
    GO
    CREATE TABLE dbo.Fatture (
    	F_Ese int,
    	F_Tipo int
    	);
    CREATE TABLE dbo.FRighe (
    	FR_Ese int,
    	FR_CodArt varchar(5),
    	FR_Desc varchar(5),
    	FR_Qta int,
    	FR_Tipo int, 
    	FR_ImportoRiga decimal(18, 4),
    	FR_Um int
    	);
    GO
    INSERT INTO dbo.Fatture
    	VALUES	( 2017, 1 ), ( 2017, 14 ),
    			( 2018, 1 ), ( 2018, 14 );
    
    INSERT INTO dbo.FRighe
    	VALUES ( 2017, 'a1', 'd1', 1, 1, 1, 1 )
    		, ( 2017, 'a2', 'd1', 1, 1, 2, 1 )
    		, ( 2017, 'a1', 'd1', 1, 14, 3, 1 );
    
    INSERT INTO dbo.FRighe
    	VALUES ( 2018, 'a1', 'd1', 1, 1, 1, 1 )
    		, ( 2018, 'a2', 'd1', 1, 1, 2, 1 )
    		, ( 2018, 'a1', 'd1', 1, 14, 3, 1 )
    		, ( 2018, 'a2', 'd1', 1, 14, 4, 1 );
    GO
    DECLARE @ese int = 2018 -- param in ingresso
    
    DECLARE @esePrec int =@ese -1; -- dichiarazione dell'Anno Precedente
    
    SELECT r.[FR_CodArt], r.[FR_Desc], r.[FR_Um]
    
    	, SUM( CASE WHEN r.[FR_Ese] = @ese THEN r.[FR_Qta]
    			ELSE 0 
    			END 
    		) AS [Qta]
    	, SUM(
    		CASE WHEN r.[FR_Ese] = @ese THEN
    			CASE WHEN r.[FR_Tipo] = 14 THEN r.[FR_ImportoRiga] *-1 ELSE r.[FR_ImportoRiga] END
    		ELSE 0.00
    		END) AS [Fatt]
    
    	, SUM( CASE WHEN r.[FR_Ese] = @esePrec THEN r.[FR_Qta]
    			ELSE 0 
    			END 
    		) AS [QtaPrec]
    	, SUM(
    		CASE WHEN r.[FR_Ese] = @esePrec THEN
    			CASE WHEN r.[FR_Tipo] = 14 THEN r.[FR_ImportoRiga] *-1 ELSE r.[FR_ImportoRiga] END
    		ELSE 0.00
    		END) AS [FattPrec]
    
    	, ROW_NUMBER() OVER(ORDER BY r.[FR_CodArt]) as [Riga]
    
    	FROM [dbo].[Fatture] f
    		JOIN [dbo].[FRighe] r ON r.[FR_Tipo] = f.[F_Tipo] AND r.[FR_Ese] = f.[F_Ese] -- AND .....
    	WHERE r.[FR_Ese] IN ( @esePrec, @ese ) --- AND
    	GROUP BY r.[FR_CodArt], r.[FR_Desc], r.[FR_Um]
    	ORDER BY r.[FR_CodArt];
    
    GO
    DROP TABLE dbo.FRighe, dbo.Fatture;
    --<-----------
    FR_CodArt FR_Desc FR_Um       Qta         Fatt      QtaPrec     FattPrec  Riga
    --------- ------- ----------- ----------- --------- ----------- --------- -----
    a1        d1      1           2           -2.0000   2           -2.0000   1
    a2        d1      1           2           -2.0000   1           2.0000    2
    
    
    se sei su SQL Server (come da forum presente), tra l'altro, vedo che referenzi gli oggetti a livello di Tabella/Vista senza specificare lo "schema" di appartenenza, quindi utilizzi chiamate non FULL QUALIFIED. Questo NON permette all'optimizer di SQL Server di riutilizzare il piano di esecuzione della query, che verra' sempre ricompilata ad ogni successiva, sprecando quindi molte risorse sia a livello di memoria, di IO, che di mero tempo di esecuzione finale... considera che il tokenizer deve in questo caso anche verificare nell'intero catalogo per tutti gli schemi quale sia l'oggetto referenziato (magari duplicato, e questo sarebbe l'unico caso corretto di non utilizzo di non qualificare completamente l'oggetto) disponibile nelle autorizzazioni dell'esecutore della query...

    saluti
    --
    Andrea
  • Re: Query confronto dati di 2 Esercizi

    Grazie mille per la dritta...
    La metto subito in produzione.
    Da solo non ci sarei mai arrivato.
Devi accedere o registrarti per scrivere nel forum
2 risposte