Minha sugestão sempre que você estiver trabalhando com PIVOT é sempre escrever a consulta primeiro com os valores codificados, então você pode facilmente converter a consulta em uma solução dinâmica.
Como você terá vários valores de
columnC
que será convertido em colunas, então você precisa olhar usando o row_number()
função de janela para gerar uma sequência única para cada columnc
com base nos valores de columnA
e columnB
. O ponto de partida para sua consulta será:
select [ColumnA],
[ColumnB],
[ColumnC],
'SampleTitle'+
cast(row_number() over(partition by columna, columnb
order by columnc) as varchar(10)) seq
from DataSource;
Veja Demonstração. Esta consulta irá gerar a lista de novos nomes de colunas
SampleTitle1
, etc:| COLUMNA | COLUMNB | COLUMNC | SEQ |
|---------|---------|---------|--------------|
| 5060 | 1006 | 100118 | SampleTitle1 |
| 5060 | 1006 | 100119 | SampleTitle2 |
| 5060 | 1006 | 100120 | SampleTitle3 |
Você pode então aplicar o pivô em
columnC
com os novos nomes de coluna listados em 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;
Consulte SQL Fiddle com demonstração.
Depois de ter a lógica correta, você pode converter os dados em SQL dinâmico. A chave aqui é gerar a lista de novos nomes de coluna. Eu normalmente uso
FOR XML PATH
para isso semelhante 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,'')
Veja Demonstração. Depois de ter a lista de nomes de colunas, você gerará sua string sql para executar, o código completo será:
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;
Consulte SQL Fiddle com demonstração. Estes dão um resultado:
| COLUMNA | COLUMNB | SAMPLETITLE1 | SAMPLETITLE2 | SAMPLETITLE3 |
|---------|---------|--------------|--------------|--------------|
| 5060 | 1006 | 100118 | 100119 | 100120 |
| 5060 | 1007 | 100121 | 100122 | (null) |
| 5060 | 1012 | 100123 | (null) | (null) |