Mijn suggestie wanneer u met PIVOT werkt, is om de query altijd eerst te schrijven met de waarden hardgecodeerd, waarna u de query eenvoudig kunt converteren naar een dynamische oplossing.
Aangezien u meerdere waarden van columnC
. zult hebben dat zal worden geconverteerd naar kolommen, dan moet je kijken naar het gebruik van de row_number()
vensterfunctie om een unieke reeks te genereren voor elke columnc
gebaseerd op de waarden van columnA
en columnB
.
Het startpunt voor uw vraag is:
select [ColumnA],
[ColumnB],
[ColumnC],
'SampleTitle'+
cast(row_number() over(partition by columna, columnb
order by columnc) as varchar(10)) seq
from DataSource;
Zie demo. Deze query genereert de lijst met nieuwe kolomnamen SampleTitle1
, enz:
| COLUMNA | COLUMNB | COLUMNC | SEQ |
|---------|---------|---------|--------------|
| 5060 | 1006 | 100118 | SampleTitle1 |
| 5060 | 1006 | 100119 | SampleTitle2 |
| 5060 | 1006 | 100120 | SampleTitle3 |
U kunt dan de spil toepassen op columnC
met de nieuwe kolomnamen vermeld 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;
Zie SQL Fiddle met demo.
Zodra u de juiste logica heeft, kunt u de gegevens converteren naar dynamische SQL. De sleutel hier is het genereren van de lijst met nieuwe kolomnamen. Ik gebruik meestal FOR XML PATH
hiervoor vergelijkbaar met:
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,'')
Zie demo. Zodra u de lijst met kolomnamen hebt, genereert u uw sql-tekenreeks om uit te voeren, de volledige code is:
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;
Zie SQL Fiddle met demo. Deze geven een resultaat:
| COLUMNA | COLUMNB | SAMPLETITLE1 | SAMPLETITLE2 | SAMPLETITLE3 |
|---------|---------|--------------|--------------|--------------|
| 5060 | 1006 | 100118 | 100119 | 100120 |
| 5060 | 1007 | 100121 | 100122 | (null) |
| 5060 | 1012 | 100123 | (null) | (null) |