>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