>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