Vous pouvez utiliser l'unpivot/pivot pour obtenir le résultat souhaité. Vous pouvez obtenir le résultat de différentes manières. Si vous avez un nombre limité de valeurs, vous pouvez coder en dur la requête, mais si vous avez un nombre inconnu de valeurs, vous devrez utiliser du SQL dynamique.
Le processus UNPIVOT convertira les multiples colonnes de c1
, etc` en plusieurs lignes. Une fois que les données sont dans plusieurs lignes, vous pouvez facilement appliquer la fonction PIVOT. Vous pouvez utiliser la fonction unpivot ou CROSS APPLY pour convertir les données de plusieurs colonnes :
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)
Voir SQL Fiddle avec démo . L'application croisée convertira vos données au format :
| 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 |
Une fois que les données sont dans ce format, vous pouvez appliquer 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;
Voir SQL Fiddle avec démo .
Ensuite, si vous avez un nombre inconnu de valeurs, vous pouvez convertir la requête ci-dessus en SQL dynamique :
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;
Voir SQL Fiddle avec démo . Les deux donneront un résultat :
| ID | SERVICEA_C1_1 | SERVICEA_CN_1 | SERVICEB_C1_2 | SERVICEB_CN_2 |
| 1 | 5 | 3 | 2 | 1 |
| 2 | 9 | 4 | (null) | (null) |