Ma suggestion chaque fois que vous travaillez avec PIVOT est de toujours écrire la requête en premier avec les valeurs codées en dur, puis vous pouvez facilement convertir la requête en une solution dynamique.
Puisque vous allez avoir plusieurs valeurs de columnC
qui seront convertis en colonnes, alors vous devez regarder en utilisant le row_number()
fonction de fenêtrage pour générer une séquence unique pour chaque columnc
basé sur les valeurs de columnA
et columnB
.
Le point de départ de votre requête sera :
select [ColumnA],
[ColumnB],
[ColumnC],
'SampleTitle'+
cast(row_number() over(partition by columna, columnb
order by columnc) as varchar(10)) seq
from DataSource;
Voir Démo. Cette requête va générer la liste des nouveaux noms de colonnes SampleTitle1
, etc :
| COLUMNA | COLUMNB | COLUMNC | SEQ |
|---------|---------|---------|--------------|
| 5060 | 1006 | 100118 | SampleTitle1 |
| 5060 | 1006 | 100119 | SampleTitle2 |
| 5060 | 1006 | 100120 | SampleTitle3 |
Vous pouvez ensuite appliquer le pivot sur columnC
avec les nouveaux noms de colonnes répertoriés dans 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;
Voir SQL Fiddle avec démo.
Une fois que vous avez la bonne logique, vous pouvez convertir les données en SQL dynamique. La clé ici est de générer la liste des nouveaux noms de colonne. J'utilise généralement FOR XML PATH
pour cela similaire à :
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,'')
Voir Démo. Une fois que vous avez la liste des noms de colonnes, alors vous allez générer votre chaîne sql à exécuter, le code complet sera :
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;
Voir SQL Fiddle avec démo. Celles-ci donnent un résultat :
| COLUMNA | COLUMNB | SAMPLETITLE1 | SAMPLETITLE2 | SAMPLETITLE3 |
|---------|---------|--------------|--------------|--------------|
| 5060 | 1006 | 100118 | 100119 | 100120 |
| 5060 | 1007 | 100121 | 100122 | (null) |
| 5060 | 1012 | 100123 | (null) | (null) |