Můj návrh, kdykoli pracujete s PIVOTem, je vždy nejprve napsat dotaz s pevně zakódovanými hodnotami, poté můžete dotaz snadno převést na dynamické řešení.
Protože budete mít více hodnot columnC
které budou převedeny na sloupce, pak se musíte podívat na pomocí row_number()
funkce okna pro generování jedinečné sekvence pro každý columnc
na základě hodnot columnA
a columnB
.
Výchozím bodem pro váš dotaz bude:
select [ColumnA],
[ColumnB],
[ColumnC],
'SampleTitle'+
cast(row_number() over(partition by columna, columnb
order by columnc) as varchar(10)) seq
from DataSource;
Viz Demo. Tento dotaz vygeneruje seznam názvů nových sloupců SampleTitle1
atd.:
| COLUMNA | COLUMNB | COLUMNC | SEQ |
|---------|---------|---------|--------------|
| 5060 | 1006 | 100118 | SampleTitle1 |
| 5060 | 1006 | 100119 | SampleTitle2 |
| 5060 | 1006 | 100120 | SampleTitle3 |
Poté můžete použít pivot na columnC
s novými názvy sloupců uvedenými v 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;
Viz SQL Fiddle with Demo.
Jakmile budete mít správnou logiku, můžete data převést na dynamický SQL. Klíčem je zde vygenerování seznamu nových názvů sloupců. Obvykle používám FOR XML PATH
pro toto podobné:
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,'')
Viz Demo. Jakmile budete mít seznam názvů sloupců, vygenerujete svůj řetězec SQL, který chcete spustit, úplný kód bude:
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;
Viz SQL Fiddle s ukázkou. Výsledkem je:
| COLUMNA | COLUMNB | SAMPLETITLE1 | SAMPLETITLE2 | SAMPLETITLE3 |
|---------|---------|--------------|--------------|--------------|
| 5060 | 1006 | 100118 | 100119 | 100120 |
| 5060 | 1007 | 100121 | 100122 | (null) |
| 5060 | 1012 | 100123 | (null) | (null) |