Muchos temas los pasamos por alto mientras no lo necesitamos… hasta que lo tenemos encima y nos ponemos a escarbar en nuestro cerebro busando una solucion.
Esta semana tenia que hacer un listado de guias con sus respectivos documentos de cobranza, por lo general tienen uno, pero a veces tienen 2 o mas, siendo anuladas o de otro tipo de comprobante, lo que implica que los documentos estan distribuidos en diferentes tablas.
Hice un ejemplo primario para lograr el objetivo deseado: convertir las filas en columnas, en este caso especifico, mostrar los detalles de un registro principal (maestro) como columnas adicionales.
Las soluciones que encontre en internet implicaban usar cursores, consultas dinamicas larguisimas, y sobre todo un codigo bastante complejo, pero me sirvió de base para construir una solucion mas sencilla, de hecho el consumo de recursos puede mantenerse igual (no he probado este tema), pero la forma de hacerlo es mas entendible a simple vista. Y tambien es necesario poner un limite en el numero de detalles, pero nuevamente es facil de aumentar esa capacidad, eso veremos en el ejemplo.
La idea fue hacer unas tablas temporales para un grupo musical y sus integrantes y mostrar en una sola fila cada grupo y sus integrantes como filas adicionales. Veamos en codigo, que se nos da mejor 
-- grupo musical
create table #_grupo(
id int identity(1, 1) primary key,
nombre nvarchar(32) not null
);
-- integrantes del grupo
create table #_cantante(
id int identity(1, 1) primary key,
grupoid int not null,
nombre nvarchar(32),
ok bit
);
-- tabla de resultados.
-- se debe asumir un limite. en este caso 6 integrantes como maximo.
create table #_ext(
id int primary key,
nombre nvarchar(32) not null,
i1 nvarchar(32) null,
i2 nvarchar(32) null,
i3 nvarchar(32) null,
i4 nvarchar(32) null,
i5 nvarchar(32) null,
i6 nvarchar(32) null
)
-- rellenado de datos.
declare @i int;
insert into #_grupo(nombre) values ('Aroma');
set @i = scope_identity();
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Teresa', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Susan', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Cinthya', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Liz Karen', 0);
insert into #_grupo(nombre) values ('Rihanna');
set @i = scope_identity();
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Rihanna', 0);
insert into #_grupo(nombre) values ('Agua Bella');
set @i = scope_identity();
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Marina', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Giuliana', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Esther', 0);
insert into #_grupo(nombre) values ('Tremendas');
set @i = scope_identity();
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Vanesa', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Milagros', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Debora', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Diana', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Karla', 0);
insert into #_grupo(nombre) values ('Alma Bella');
set @i = scope_identity();
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Maricarmen', 0);
insert into #_cantante (grupoid, nombre, ok) values (@i, 'Alheli', 0);
insert into #_ext(id, nombre) select id, nombre from #_grupo;
-- visualizaciones basicas
--select * from #_grupo;
--select * from #_cantante;
-- un conteo
--select g.id, g.nombre, 'integrates' = count(c.id) from #_grupo g
--inner join #_cantante c on g.id = c.grupoid
--group by g.id, g.nombre;
-- la vista general que queremos invertir
--select g.id, g.nombre, c.nombre from #_grupo g
--inner join #_cantante c on g.id = c.grupoid;
-- agrupacion de detalles en el maestro.
declare @k int;
declare @query nvarchar(1024);
set @k = 1;
while @k <= 6
begin
-- query base para construir el query dinamico.
-- update #_ext set i1 = c.nombre from #_cantante c where c.grupoid = #_ext.id and c.ok = 0;
set @query = N'update #_ext set i' + ltrim(rtrim(convert(nvarchar(8), @k))) + N' = c.nombre from #_cantante c where c.grupoid = #_ext.id and c.ok = 0';
execute(@query);
-- query base para construir el query dinamico.
--update #_cantante set ok = 1 from #_ext where i1 = #_cantante.nombre;
set @query = N'update #_cantante set ok = 1 from #_ext where i' + ltrim(rtrim(convert(nvarchar(8), @k))) + N' = #_cantante.nombre';
execute(@query);
set @k = @k + 1;
end
-- mostrar el resultado deseado
select 'grupo'= nombre, 'principal'=i1, '2º voz'=i2, 'bailarina 1'=i3, 'bailarina 2'=i4, 'bailarina 3'=i5, 'bailarina 4'=i6 from #_ext;
-- ser buenos ciudadanos.
drop table #_grupo;
drop table #_cantante;
drop table #_ext;