Il mio suggerimento ogni volta che si lavora con PIVOT è di scrivere sempre la query prima con i valori codificati, quindi è possibile convertire facilmente la query in una soluzione dinamica.
Dal momento che avrai più valori di columnC
che verrà convertito in colonne, quindi devi guardare usando il row_number()
funzione di windowing per generare una sequenza univoca per ogni columnc
in base ai valori di columnA
e columnB
.
Il punto di partenza per la tua richiesta sarà:
select [ColumnA],
[ColumnB],
[ColumnC],
'SampleTitle'+
cast(row_number() over(partition by columna, columnb
order by columnc) as varchar(10)) seq
from DataSource;
Vedi Demo. Questa query genererà l'elenco dei nuovi nomi di colonne SampleTitle1
, ecc:
| COLUMNA | COLUMNB | COLUMNC | SEQ |
|---------|---------|---------|--------------|
| 5060 | 1006 | 100118 | SampleTitle1 |
| 5060 | 1006 | 100119 | SampleTitle2 |
| 5060 | 1006 | 100120 | SampleTitle3 |
Puoi quindi applicare il pivot su columnC
con i nuovi nomi di colonna elencati in seq
:
select columnA, columnB,
SampleTitle1, SampleTitle2, SampleTitle3
from
(
select [ColumnA],
[ColumnB],
[ColumnC],
'SampleTitle'+
cast(row_number() over(partition by columna, columnb
order by columnc) as varchar(10)) seq
from DataSource
) d
pivot
(
max(columnc)
for seq in (SampleTitle1, SampleTitle2, SampleTitle3)
) piv;
Vedi SQL Fiddle con demo.
Una volta che hai la logica corretta, puoi convertire i dati in SQL dinamico. La chiave qui sta generando l'elenco dei nuovi nomi di colonna. Di solito uso FOR XML PATH
per questo simile a:
select STUFF((SELECT distinct ',' + QUOTENAME(seq)
from
(
select 'SampleTitle'+
cast(row_number() over(partition by columna, columnb
order by columnc) as varchar(10)) seq
from DataSource
) d
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
Vedi Demo. Una volta che hai l'elenco dei nomi delle colonne, genererai la tua stringa sql da eseguire, il codice completo sarà:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(seq)
from
(
select 'SampleTitle'+
cast(row_number() over(partition by columna, columnb
order by columnc) as varchar(10)) seq
from DataSource
) d
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT columnA, ColumnB,' + @cols + '
from
(
select [ColumnA],
[ColumnB],
[ColumnC],
''SampleTitle''+
cast(row_number() over(partition by columna, columnb
order by columnc) as varchar(10)) seq
from DataSource
) x
pivot
(
max(columnc)
for seq in (' + @cols + ')
) p '
execute sp_executesql @query;
Vedere SQL Fiddle con demo. Questi danno un risultato:
| COLUMNA | COLUMNB | SAMPLETITLE1 | SAMPLETITLE2 | SAMPLETITLE3 |
|---------|---------|--------------|--------------|--------------|
| 5060 | 1006 | 100118 | 100119 | 100120 |
| 5060 | 1007 | 100121 | 100122 | (null) |
| 5060 | 1012 | 100123 | (null) | (null) |