Puede usar unpivot/pivot para obtener el resultado que desea. Hay algunas formas diferentes de obtener el resultado, si tiene un número limitado de valores, puede codificar la consulta, pero si tiene un número desconocido de valores, necesitará usar SQL dinámico.
El proceso UNPIVOT convertirá las múltiples columnas de c1
, etc` en varias filas. Una vez que los datos están en varias filas, puede aplicar fácilmente la función PIVOT. Puede usar la función de no pivotar o APLICACIÓN CRUZADA para convertir los datos de varias columnas:
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)
Consulte SQL Fiddle con demostración . La aplicación cruzada convertirá sus datos al formato:
| 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 |
Una vez que los datos estén en este formato, puede aplicar 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;
Consulte SQL Fiddle con demostración .
Luego, si tiene un número desconocido de valores, puede convertir la consulta anterior a SQL dinámico:
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;
Consulte SQL Fiddle con demostración . Ambos darán un resultado:
| ID | SERVICEA_C1_1 | SERVICEA_CN_1 | SERVICEB_C1_2 | SERVICEB_CN_2 |
| 1 | 5 | 3 | 2 | 1 |
| 2 | 9 | 4 | (null) | (null) |