Creazione di una tabella calendario

lunedì 30 ottobre 2017 - 17.17
Tag Elenco Tags  SQL Server 2008 R2

vittosss Profilo | Junior Member

Ciao,
cerco di spiegarvi al meglio.
io ho una tabella con tre colonne:
Utente
Data
Attività
nella colonna utente, va da se, ho una serie di nomi.
nella colonna data, la data che identifica quando è stata svolta l'attività.
tipo di attività

quello che vorrei fare, credo, si chiami pivot, ovvero produrre una tabella, o un report, che sull'asse delle x ha i giorni del mese e sull'asse delle y il nome utente. in mezzo l'attività incasellata.

grazie mille!!

amontanari Profilo | Newbie

>Ciao,
>cerco di spiegarvi al meglio.
>io ho una tabella con tre colonne:
>Utente
>Data
>Attività
>nella colonna utente, va da se, ho una serie di nomi.
>nella colonna data, la data che identifica quando è stata svolta
>l'attività.
>tipo di attività
>
>quello che vorrei fare, credo, si chiami pivot, ovvero produrre
>una tabella, o un report, che sull'asse delle x ha i giorni del
>mese e sull'asse delle y il nome utente. in mezzo l'attività
>incasellata.
>
>grazie mille!!

salve, anche se in ritardo...
parto dal presupposto che la rotazione temporale in colonna, giustamente chiamata operazione di PIVOTing, debba avvenire in maniera in qualche modo dinamica in base all'arco temporale passato come probabile parametro...
in questo senso NON si puo' fare un'operazione "ordinaria" di PIVOT in quanto il comando NON supporta specifiche dinamiche ma solo costanti hard coded nel codice... quindi la soluzione tipicamente utilizzata e' la costruzione di un comando dinamico quindi eseguito tramite sp_executesql, la stored procedure di sistema atta ad eseguire codice dinamico...
in questo senso, personalmente, costruirei una tabella [calendario] da utilizzare in JOIN con la nostra tabella [attivita] in modo da avere l'intera finestra temporale... nel caso invece ti bastino le SOLE date di attivita' questa parte puo' essere omessa... quindi in base alle {date} presenti nel risultato calendarizzato, si puo' costruire l'asse delle X, cioe' la proiezione di tutte le colonne intese come date della finestra... qui poi si inserisce la funzionalita' di PIVOTing prevista dal T-SQL...
trivialmente,
SET NOCOUNT ON; GO USE tempdb; GO CREATE TABLE dbo.t ( Utente varchar(10), Data date, Attivita int ); INSERT INTO dbo.t VALUES ('A', '2018-01-01', 1); INSERT INTO dbo.t VALUES ('A', '2018-01-02', 1); INSERT INTO dbo.t VALUES ('A', '2018-01-03', 2); INSERT INTO dbo.t VALUES ('A', '2018-01-05', 1); INSERT INTO dbo.t VALUES ('A', '2018-01-07', 3); INSERT INTO dbo.t VALUES ('B', '2018-01-01', 2); INSERT INTO dbo.t VALUES ('B', '2018-01-03', 1); INSERT INTO dbo.t VALUES ('B', '2018-01-04', 1); INSERT INTO dbo.t VALUES ('B', '2018-01-07', 2); GO PRINT 'otteniamo un Calendario per avere anche le date vuote'; DECLARE @dMin date, @dMax date; SELECT @dMin = MIN(t.Data), @dMax = MAX(t.Data) FROM dbo.t t; --SELECT @dMin, @dMax; WITH cteCalendar AS ( SELECT @dMin AS Data UNION ALL SELECT DATEADD(DAY, 1, Data) FROM cteCalendar WHERE Data < @dMax ) SELECT * FROM cteCalendar OPTION (MAXRECURSION 0); GO DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX); SET @columns = N''; DECLARE @dMin date, @dMax date; SELECT @dMin = MIN(t.Data), @dMax = MAX(t.Data) FROM dbo.t t; WITH cteCalendar AS ( SELECT @dMin AS Data UNION ALL SELECT DATEADD(DAY, 1, Data) FROM cteCalendar WHERE Data < @dMax ) SELECT @columns += N', p.' + QUOTENAME(Data) FROM (SELECT c.Data FROM cteCalendar c ) AS x; --SELECT @columns; --SELECT t.Utente, t.Attivita -- FROM dbo.t t PRINT 'Costruiamo dinamicamente la rotazione in colonna di tutta la finestra temporale..'; SET @sql = N' DECLARE @dMin date, @dMax date; DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX); SELECT @dMin = MIN(t.Data), @dMax = MAX(t.Data) FROM dbo.t t; WITH cteCalendar AS ( SELECT @dMin AS Data UNION ALL SELECT DATEADD(DAY, 1, Data) FROM cteCalendar WHERE Data < @dMax ) SELECT ' + STUFF(@columns, 1, 2, '') + ' FROM ( SELECT t.Utente, t.Attivita, t.Data FROM dbo.t t INNER JOIN cteCalendar c ON c.Data = t.Data ) AS j PIVOT ( MIN(Attivita) FOR Data IN (' + STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '') + ') ) AS p;'; --PRINT @sql; PRINT 'esecuzione...'; EXEC sp_executesql @sql; GO DROP TABLE dbo.t; --<------------- otteniamo un Calendario per avere anche le date vuote Data ---------- 2018-01-01 2018-01-02 2018-01-03 2018-01-04 2018-01-05 2018-01-06 2018-01-07 Costruiamo dinamicamente la rotazione in colonna di tutta la finestra temporale.. esecuzione... 2018-01-01 2018-01-02 2018-01-03 2018-01-04 2018-01-05 2018-01-06 2018-01-07 ----------- ----------- ----------- ----------- ----------- ----------- ----------- 1 1 2 NULL 1 NULL 3 2 NULL 1 1 NULL NULL 2

saluti (sempre in ritardo)
--
Andrea Montanari
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