Pivot, CROSS JOIN, Cosa devo usare ?? ! Aiutatemi !!

domenica 25 gennaio 2009 - 09.33

gmt Profilo | Junior Member

Parliamo di SQL Server 2005.. Nella tabella1 ho un periodo, nella tabella 2 i valori, nella tabella 3 delle anagrafiche.. le join dovrebbero essere semplici..
io vorrei il seguente risultato.. (sotto vi ho creato le tabelle e i valori)..

Genn 09 Febb 09 Marz 09 Apr 09
1 Gianni 10 13 null null
2 Pepp 12 null null null
3 Antonio null null null 15
4 Romolo null null null null

La tabella 1 potrebbe avere anche piu' record, aggiunti dall'utente.. quindi non vincolarla nella query creata..
Chi puo' aiutarmi?
Grazie

create table #temp1 (id smallint, periodo nvarchar(10))
insert into #temp1 values (1, 'Genn 09')
insert into #temp1 values (2, 'Febb 09')
insert into #temp1 values (3, 'Marz 09')
insert into #temp1 values (4, 'Apr 09')

create table #temp2 (id smallint, fkidperiodo smallint, fkidanagrafica smallint, valore int)

insert into #temp2 values (1,1,1, 10)
insert into #temp2 values (2,1,2, 12)
insert into #temp2 values (3,2,1, 13)
insert into #temp2 values (4,4,3, 15)

create table #temp3 (id smallint, nome nvarchar(100))

insert into #temp3 values (1, 'Gianni')
insert into #temp3 values (2, 'Peppe')
insert into #temp3 values (3, 'Antonio')
insert into #temp3 values (4, 'Romolo')


drop table #temp1
drop table #temp2
drop table #temp3

lbenaglia Profilo | Guru

>Chi puo' aiutarmi?
Io

Osserva il seguente esempio:

USE tempdb; CREATE TABLE dbo.Periodi( id smallint NOT NULL PRIMARY KEY, periodo nvarchar(10) NOT NULL ); CREATE TABLE dbo.Utenti( id smallint NOT NULL PRIMARY KEY, nome nvarchar(10) NOT NULL ); CREATE TABLE dbo.PeriodiUtenti( id smallint NOT NULL PRIMARY KEY, fkidperiodo smallint NOT NULL, fkidanagrafica smallint NOT NULL, valore int NOT NULL, CONSTRAINT FK_PeriodiUtenti_Periodi FOREIGN KEY(fkidperiodo) REFERENCES dbo.Periodi(id), CONSTRAINT FK_PeriodiUtenti_Utenti FOREIGN KEY(fkidanagrafica) REFERENCES dbo.Utenti(id) ); INSERT dbo.Periodi VALUES (1, 'Genn 09'); INSERT dbo.Periodi VALUES (2, 'Febb 09'); INSERT dbo.Periodi VALUES (3, 'Marz 09'); INSERT dbo.Periodi VALUES (4, 'Apr 09'); INSERT dbo.Utenti VALUES (1, 'Gianni'); INSERT dbo.Utenti VALUES (2, 'Peppe'); INSERT dbo.Utenti VALUES (3, 'Antonio'); INSERT dbo.Utenti VALUES (4, 'Romolo'); INSERT dbo.PeriodiUtenti VALUES (1, 1, 1, 10); INSERT dbo.PeriodiUtenti VALUES (2, 1, 2, 12); INSERT dbo.PeriodiUtenti VALUES (3, 2, 1, 13); INSERT dbo.PeriodiUtenti VALUES (4, 4, 3, 15); SELECT id , nome , [Genn 09] AS 'Genn 09' , [Febb 09] AS 'Febb 09' , [Marz 09] AS 'Marz 09' , [Apr 09] AS 'Apr 09' FROM ( SELECT U.id , U.nome , P.periodo , PU.valore FROM dbo.Utenti AS U LEFT JOIN dbo.PeriodiUtenti AS PU ON U.id = PU.fkidanagrafica LEFT JOIN dbo.Periodi AS P ON PU.fkidperiodo = P.id ) AS Q PIVOT ( MAX(valore) FOR periodo IN ([Genn 09], [Febb 09], [Marz 09], [Apr 09]) ) AS pvt ORDER BY id; /* Output: id nome Genn 09 Febb 09 Marz 09 Apr 09 ------ ---------- ----------- ----------- ----------- ----------- 1 Gianni 10 13 NULL NULL 2 Peppe 12 NULL NULL NULL 3 Antonio NULL NULL NULL 15 4 Romolo NULL NULL NULL NULL (4 row(s) affected) */ DROP TABLE dbo.PeriodiUtenti, dbo.Periodi, dbo.Utenti;

Tieni presente che l'operatore PIVOT non permette la scrittura di di query crosstab dinamiche, pertanto dovrai prevedere tutte le colonne che ti servono (io mi sono limitato ai primi 4 mesi).

>Grazie
Prego.

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

gmt Profilo | Junior Member

Qui ci ero (quasi) arrivato.. il problema è che il periodo è una tabella valorizzata dall'utente.. potrei costringerlo con valori messi fissi da me.. ma sarei costretto a modificare la query e la tabella ogni anno nuovo xchè devo aggiungere i nuovi periodi..
murble.. murble.. vedo di trovare un compromesso..

Cmq Grazie..
Ciao

lbenaglia Profilo | Guru

>Qui ci ero (quasi) arrivato.. il problema è che il periodo è
>una tabella valorizzata dall'utente.. potrei costringerlo con
>valori messi fissi da me.. ma sarei costretto a modificare la
>query e la tabella ogni anno nuovo xchè devo aggiungere i nuovi
>periodi..
>murble.. murble.. vedo di trovare un compromesso..

Definisci una sp che crei un comando di PIVOT dinamico in base al contenuto delle tabelle, eseguendo il tutto via EXECUTE.

>Cmq Grazie..
Cmq prego

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

gmt Profilo | Junior Member

Fatto anche con l'aiutino del seguenti link

http://www.ugiss.org/Content/Article/PIVOT-dinamico-in-SQL-Server-2005.aspx

Bye
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