Newsgroup: it.comp.software.database
Titolo: SQL2000 e "campi incrociati"

Ciao a tutti,
volevo sapere se qualcuno di voi ha mai implementato qualcosa di simile alle
query a campi incrociati di Access in SQL2000, e nel caso affermativo mi
piacerebbe avere una dritta su come fare.
Grazie

 wrote in message 
news:as4nr2$12ql$1...@news6.isdnet.net...

Ciao Luigi,
SQL Server non supporto (per il momento) niente di simile in
maniera pratica.
Ci sono comunque diverse tecniche.
Crosstab tramite subqueries per ottenere il numero di ordini per
cliente e per anno:
USE Northwind
SELECT CU.CompanyName AS Cliente,
 (SELECT COUNT(*) FROM Orders AS O1 WHERE O1.CustomerID = OD.CustomerID 
AND
YEAR(O1.OrderDate) = 1996) AS Ordini_1996,
 (SELECT COUNT(*) FROM Orders AS O1 WHERE O1.CustomerID = OD.CustomerID 
AND
YEAR(O1.OrderDate) = 1997) AS Ordini_1997,
 (SELECT COUNT(*) FROM Orders AS O1 WHERE O1.CustomerID = OD.CustomerID 
AND
YEAR(O1.OrderDate) = 1998) AS Ordini_1998
FROM Orders AS OD
JOIN Customers AS CU
ON OD.CustomerID = CU.CustomerID
GROUP BY
 OD.CustomerID, CU.CompanyName
-- Se vuoi puoi aggiungere anche un campo che calcola il totale
-- per tutti gli anni presi in considerazione
SELECT CU.CompanyName AS Cliente,
 (SELECT COUNT(*) FROM Orders AS O1 WHERE O1.CustomerID = OD.CustomerID 
AND
YEAR(O1.OrderDate) = 1996) AS Ordini_1996,
 (SELECT COUNT(*) FROM Orders AS O1 WHERE O1.CustomerID = OD.CustomerID 
AND
YEAR(O1.OrderDate) = 1997) AS Ordini_1997,
 (SELECT COUNT(*) FROM Orders AS O1 WHERE O1.CustomerID = OD.CustomerID 
AND
YEAR(O1.OrderDate) = 1998) AS Ordini_1998,
 (SELECT COUNT(*) FROM Orders AS O1 WHERE O1.CustomerID = OD.CustomerID 
AND
YEAR(O1.OrderDate) BETWEEN 1996 AND 1998) AS Ordini_Totale
FROM Orders AS OD
JOIN Customers AS CU
ON OD.CustomerID = CU.CustomerID
GROUP BY
 OD.CustomerID, CU.CompanyName
Utilizzo di una matrice per ottenere lo stesso risultato:
CREATE TABLE #tmp_cross (
 Anno  smallint  NOT NULL PRIMARY KEY,
 Ord_1996 tinyint  NOT NULL,
 Ord_1997 tinyint  NOT NULL,
 Ord_1998 tinyint  NOT NULL,
)
INSERT #tmp_cross VALUES(1996, 1, 0, 0)
INSERT #tmp_cross VALUES(1997, 0, 1, 0)
INSERT #tmp_cross VALUES(1998, 0, 0, 1)
SELECT CU.CompanyName AS Cliente,
 SUM(TC.Ord_1996) AS Ordini_1996,
 SUM(TC.Ord_1997) AS Ordini_1997,
 SUM(TC.Ord_1998) AS Ordini_1998
FROM #tmp_cross AS TC
JOIN Orders AS OD ON TC.Anno = YEAR(OD.Orderdate)
JOIN Customers AS CU ON OD.CustomerID = CU.CustomerID
GROUP BY
 OD.CustomerID, CU.CompanyName
Questi sono solo alcuni esempi, puoi scrivere le stesse cose anche per
totalizzare valori anziche' contare (usando SUM ecc.) altri due
esempi, tra i quali quello che usa la CASE, li puoi trovare nel
seguente articolo:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q175574
L'unico problema di questi approcci e' che devi sapere in anticipo
il numero di colonne che devi generare.
Per ovviare al problema ti allego una stored procedure di
pubblico dominio che crea l'SQL dinamico, oppure puoi acquistare
un prodottino (tutto basato su stored procedure) che permette di
fare crosstab generalizzate al seguente indirizzo
http://www.angelfire.com/ny4/rac/
Tieni comunque conto che fare le crosstab senza SQL dinamico e'
piu' veloce e che spesso il fatto che il numero di colonne possa
essere variable non e' comunque accettabile (c'e' sempre un numero
massimo oltre il quale non vado altrimenti il layout stesso del
report non sarebbe piu' quello che mi aspetto).
Ultima riflessione: qualunque tecnica tu decida di utilizzare,
si tratta comunque di query piuttosto complesse che applicate a
grosse quantitą di dati hanno prestazioni piuttosto scarse.
La soluzione migliore spesso sta' nel delegare al prodotto
che compone il report la cross-tabulazione dei valori.
Ciao,
--
Gianluca Hotz
Backoffice MVP (SQL Server) MCP SQL Server and MCP Windows
Vice-President of the Italian User Group for SQL Server
Founding Member of the Italian User Group for .NET
http://www.ghotz.com
http://www.ugiss.org

 wrote in message
news:as4nr2$12ql$1...@news6.isdnet.net...
Ciao Luigi,

Come ti ha già anticipato Gianluca, SQL Server non nativamente offre la
possibilità di creare query a campi
incrociati.
Ad ogni modo sul numero di Novembre 2000 di SQL Server Magazine, Itzik
Ben-Gan ha
affrontato questo problema, proponendo una Stored Procedure in grado di
generare query crosstab dinamiche.
L'articolo è disponibile al seguentre link:
http://www.sqlmag.com/Articles/Index.cfm?ArticleID=15608
Ciao!
--
Lorenzo Benaglia
UGIdotNET - 
http://www.ugidotnet.org
UGISS - 
http://www.ugiss.org