Moja sugestia, gdy pracujesz z PIVOT, to zawsze najpierw pisać zapytanie z wartościami zakodowanymi na stałe, a następnie możesz łatwo przekonwertować zapytanie na dynamiczne rozwiązanie.
Ponieważ będziesz mieć wiele wartości columnC
które zostaną przekonwertowane na kolumny, musisz przyjrzeć się za pomocą row_number()
funkcja okienkowa do generowania unikalnej sekwencji dla każdej columnc
na podstawie wartości columnA
i columnB
.
Punktem wyjścia dla Twojego zapytania będzie:
select [ColumnA],
[ColumnB],
[ColumnC],
'SampleTitle'+
cast(row_number() over(partition by columna, columnb
order by columnc) as varchar(10)) seq
from DataSource;
Zobacz Demo. To zapytanie wygeneruje listę nowych nazw kolumn SampleTitle1
itp:
| COLUMNA | COLUMNB | COLUMNC | SEQ |
|---------|---------|---------|--------------|
| 5060 | 1006 | 100118 | SampleTitle1 |
| 5060 | 1006 | 100119 | SampleTitle2 |
| 5060 | 1006 | 100120 | SampleTitle3 |
Następnie możesz zastosować element przestawny na columnC
z nowymi nazwami kolumn wymienionymi w 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;
Zobacz SQL Fiddle z wersją demonstracyjną.
Gdy masz poprawną logikę, możesz przekonwertować dane na dynamiczny SQL. Kluczem jest tutaj wygenerowanie listy nowych nazw kolumn. Zwykle używam FOR XML PATH
dla tego podobnego do:
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,'')
Zobacz Demo. Gdy masz już listę nazw kolumn, wygenerujesz ciąg sql do wykonania, pełny kod będzie wyglądał następująco:
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;
Zobacz SQL Fiddle z demonstracją. Dają wynik:
| COLUMNA | COLUMNB | SAMPLETITLE1 | SAMPLETITLE2 | SAMPLETITLE3 |
|---------|---------|--------------|--------------|--------------|
| 5060 | 1006 | 100118 | 100119 | 100120 |
| 5060 | 1007 | 100121 | 100122 | (null) |
| 5060 | 1012 | 100123 | (null) | (null) |