Đề xuất của tôi bất cứ khi nào bạn làm việc với PIVOT là luôn viết truy vấn trước với các giá trị được mã hóa cứng, sau đó bạn có thể dễ dàng chuyển đổi truy vấn thành giải pháp động.
Vì bạn sẽ có nhiều giá trị của columnC
sẽ được chuyển đổi thành cột, sau đó bạn cần xem xét bằng cách sử dụng row_number()
chức năng cửa sổ để tạo một chuỗi duy nhất cho mỗi columnc
dựa trên các giá trị của columnA
và columnB
.
Điểm bắt đầu cho truy vấn của bạn sẽ là:
select [ColumnA],
[ColumnB],
[ColumnC],
'SampleTitle'+
cast(row_number() over(partition by columna, columnb
order by columnc) as varchar(10)) seq
from DataSource;
Xem Demo. Truy vấn này sẽ tạo danh sách các tên cột mới SampleTitle1
, v.v.:
| COLUMNA | COLUMNB | COLUMNC | SEQ |
|---------|---------|---------|--------------|
| 5060 | 1006 | 100118 | SampleTitle1 |
| 5060 | 1006 | 100119 | SampleTitle2 |
| 5060 | 1006 | 100120 | SampleTitle3 |
Sau đó, bạn có thể áp dụng trục trên columnC
với các tên cột mới được liệt kê trong 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;
Xem SQL Fiddle với Demo.
Khi bạn có logic chính xác, bạn có thể chuyển đổi dữ liệu sang SQL động. Chìa khóa ở đây là tạo danh sách các tên cột mới. Tôi thường sử dụng FOR XML PATH
cho điều này tương tự như:
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,'')
Xem Demo. Khi bạn có danh sách tên cột, sau đó bạn sẽ tạo chuỗi sql của mình để thực thi, mã đầy đủ sẽ là:
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;
Xem SQL Fiddle với Demo. Những điều này cho kết quả:
| COLUMNA | COLUMNB | SAMPLETITLE1 | SAMPLETITLE2 | SAMPLETITLE3 |
|---------|---------|--------------|--------------|--------------|
| 5060 | 1006 | 100118 | 100119 | 100120 |
| 5060 | 1007 | 100121 | 100122 | (null) |
| 5060 | 1012 | 100123 | (null) | (null) |