Bạn có thể sử dụng chức năng bỏ chia sẻ / pivot để nhận được kết quả mà bạn muốn. Có một số cách khác nhau để bạn có thể nhận được kết quả, nếu bạn có một số giá trị hạn chế thì bạn có thể mã hóa truy vấn nhưng nếu bạn có một số lượng giá trị không xác định thì bạn sẽ cần sử dụng SQL động.
Quá trình UNPIVOT sẽ chuyển đổi nhiều cột của c1
, vv` thành nhiều hàng. Khi dữ liệu nằm trong nhiều hàng thì bạn có thể dễ dàng áp dụng hàm PIVOT. Bạn có thể sử dụng chức năng bỏ chia hoặc ÁP DỤNG CHÉO để chuyển đổi dữ liệu từ nhiều cột:
select id,
col = 'Service'+Service+'_'+col+'_'+cast(seq as varchar(10)),
value
from
(
select id, service, c1, cn
, row_number() over(partition by id
order by service) seq
from yourtable
) t
cross apply
(
select 'c1', c1 union all
select 'cn', cn
) c (col, value)
Xem SQL Fiddle with Demo . Áp dụng chéo sẽ chuyển đổi dữ liệu của bạn sang định dạng:
| ID | COL | VALUE |
| 1 | ServiceA_c1_1 | 5 |
| 1 | ServiceA_cn_1 | 3 |
| 1 | ServiceB_c1_2 | 2 |
| 1 | ServiceB_cn_2 | 1 |
| 2 | ServiceA_c1_1 | 9 |
| 2 | ServiceA_cn_1 | 4 |
Khi dữ liệu ở định dạng này, bạn có thể áp dụng PIVOT:
select id, ServiceA_c1_1, ServiceA_cn_1,
ServiceB_c1_2, ServiceB_cn_2
from
(
select id,
col = 'Service'+Service+'_'+col+'_'+cast(seq as varchar(10)),
value
from
(
select id, service, c1, cn
, row_number() over(partition by id
order by service) seq
from yourtable
) t
cross apply
(
select 'c1', c1 union all
select 'cn', cn
) c (col, value)
) d
pivot
(
max(value)
for col in (ServiceA_c1_1, ServiceA_cn_1,
ServiceB_c1_2, ServiceB_cn_2)
) piv;
Xem SQL Fiddle with Demo .
Sau đó, nếu bạn có một số lượng giá trị không xác định, bạn có thể chuyển đổi truy vấn trên thành SQL động:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME('Service'+Service+'_'+col+'_'+cast(seq as varchar(10)))
from
(
select service,
row_number() over(partition by id
order by service) seq
from yourtable
)d
cross apply
(
select 'c1', 1 union all
select 'cn', 2
) c (col, so)
group by seq, Service, col, so
order by seq, so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT id, ' + @cols + '
from
(
select id,
col = ''Service''+Service+''_''+col+''_''+cast(seq as varchar(10)),
value
from
(
select id, service, c1, cn
, row_number() over(partition by id
order by service) seq
from yourtable
) t
cross apply
(
select ''c1'', c1 union all
select ''cn'', cn
) c (col, value)
) x
pivot
(
max(value)
for col in (' + @cols + ')
) p '
execute sp_executesql @query;
Xem SQL Fiddle with Demo . Cả hai sẽ cho một kết quả:
| ID | SERVICEA_C1_1 | SERVICEA_CN_1 | SERVICEB_C1_2 | SERVICEB_CN_2 |
| 1 | 5 | 3 | 2 | 1 |
| 2 | 9 | 4 | (null) | (null) |