Risultato query : Totali e parziali nella stessa riga

martedì 03 marzo 2009 - 13.29

andreapiro Profilo | Newbie

Neofito del sito, quindi chiedo venia di eventuali errori!

Ho una tabella che per semplicità ha i seguenti campi:
Nome
Documento
Tipodocumento
ImportoDocumento


Vorrei fare una query il cui risultato fosse, filtrato per TipoDocumento:
Nome - Documento - ImportoDocumento - Sum(importoDocumento)

Ho in mente le due query che devo unire:
Q1 : select nome, Sum(importoDocumento) from Tabella where TipoDocumento = A group by nome

Q2: Select nome,documento,Importo Documento from Tabella where Tipodocumento = A

Come faccio?

Grazie mille



alx_81 Profilo | Guru

>Neofito del sito, quindi chiedo venia di eventuali errori!
Ciao e benvenuto su DotNetHell!

>Vorrei fare una query il cui risultato fosse, filtrato per TipoDocumento:
>Nome - Documento - ImportoDocumento - Sum(importoDocumento)

>Ho in mente le due query che devo unire:
>Q1 : select nome, Sum(importoDocumento) from Tabella where TipoDocumento
>= A group by nome
>Q2: Select nome,documento,Importo Documento from Tabella where
>Tipodocumento = A
>Come faccio?
Facciamo così, visto che le due query sono diverse e non capisco perchè sono due, prova a passarmi un elenco di dati che inseriresti e il resultset che vuoi ottenere in output. Così vediamo quale query è la più adatta.

>Grazie mille
di nulla!
>
>
>
>

--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

andreapiro Profilo | Newbie

Ciao Alx
Ti ho allegato un piccolo file excel.
Prova a vedere se ci capisci:
le condizioni sono:
Voglio eliminare i documenti di tipo B
Voglio mettere sulla stessa riga di ogni singolo documento, un campo calcolato che sia la somma dell'importo dei docuemnti rimasti

Grazie

lbenaglia Profilo | Guru

>le condizioni sono:
>Voglio eliminare i documenti di tipo B
>Voglio mettere sulla stessa riga di ogni singolo documento, un
>campo calcolato che sia la somma dell'importo dei docuemnti rimasti

Ciao Andrea,

Se utilizzi SQL Server 2008 puoi servirti di un paio di Common Table Expressions e dei nuovi GROUPING SETS:

USE tempdb; CREATE TABLE dbo.Documenti( DocumentoID int NOT NULL PRIMARY KEY, Nome varchar(10) NOT NULL, Tipo char(1) NOT NULL, Importo int NOT NULL ); INSERT dbo.Documenti VALUES (1, 'Andrea', 'A', 10) , (2, 'Andrea', 'B', 20) , (3, 'Andrea', 'A', 30) , (4, 'Andrea', 'A', 40) , (5, 'Franco', 'B', 15) , (6, 'Franco', 'B', 25) , (7, 'Franco', 'A', 35) , (8, 'Massimo', 'A', 100) , (9, 'Massimo', 'B', 200) , (10, 'Massimo', 'A', 300); WITH CTE_GroupingSets AS ( SELECT Nome , DocumentoID , Importo , SUM(Importo) AS Totale FROM dbo.Documenti WHERE Tipo <> 'B' GROUP BY GROUPING SETS( (Nome, DocumentoID, Importo), (Nome) ) ), CTE_TotByName(Nome, Totale) AS ( SELECT Nome , MAX(Totale) FROM CTE_GroupingSets GROUP BY Nome ) SELECT GS.Nome , GS.DocumentoID , GS.Importo , TBN.Totale FROM CTE_GroupingSets AS GS JOIN CTE_TotByName AS TBN ON GS.Nome = TBN.Nome WHERE GS.DocumentoID IS NOT NULL; /* Output: Nome DocumentoID Importo Totale ---------- ----------- ----------- ----------- Andrea 1 10 80 Andrea 3 30 80 Andrea 4 40 80 Franco 7 35 35 Massimo 8 100 400 Massimo 10 300 400 (6 row(s) affected) */ DROP TABLE dbo.Documenti;

Come puoi notare i GROUPING SETS permettono di specificare diversi tipi di raggruppamenti in una singola query senza la necessità di "fondere" insieme i result sets di query distinte.
La seconda CTE recupera per ogni nome il valore massimo del totale calcolato in precedenza ed infine mettendo in JOIN i due result set escludendo le righe frutto dell'aggregazione per nome otterrai il risultato richiesto.

Se utilizzi versioni precedenti di SQL Server puoi sostituire le CTE con viste o tabelle derivate ed i GROUPING SETS con query distinte e l'operatore UNION:
http://technet.microsoft.com/en-us/library/bb510427.aspx

Nel caso preferissi evitare di complicarti la vita seguendo i consigli di un tipo con la mente annebbiata dalle nuove features di un prodotto (se non hai capito sto parlando di me stesso ) puoi semplicemente scrivere:

WITH CTE_Documents AS ( SELECT Nome , DocumentoID , Importo FROM dbo.Documenti WHERE Tipo <> 'B' ), CTE_TotByName(Nome, Totale) AS ( SELECT Nome , SUM(Importo) FROM CTE_Documents GROUP BY Nome ) SELECT D.Nome , D.DocumentoID , D.Importo , TBN.Totale FROM CTE_Documents AS D JOIN CTE_TotByName AS TBN ON D.Nome = TBN.Nome;

>Grazie
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

andreapiro Profilo | Newbie

In relatà Utilizzo Visual Fox Pro (magari non è neanche quesot il forum adatto.....)
Comunque adesso ci provo e vi farò sapere...

Non sono riuscito a seguire le vostre indicazioni.

Ho però aggirato il problema attraverso la creazione di una tabella in cui è presente il totale e poi con una join delle due tabelle.

A questo punto, poichè il problema mi si potrebbe ripresentare, è pensabile risolverlo attraverso l'utilizzo di una join sulla stessa tabella, senza dover creare una tabella nuova di appoggio?
Ho provato con gli alias ma on ci sono riuscito....forse devo abbandonare FoxPro e passare a qualcosaltro?
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