post icon

Como lograr Unpivot de múltiples columnas

Para hacer lo más sencilla posible la explicación de como lograr UNPIVOT con varias columnas usaremos un ejemplo simple con UNPIVOT de una sola columna primeramente. Imaginemos que tenemos una tabla de candidatos para un puesto y RRHH debe realizar las llamadas a los números de sus referencias personales y laborales para hacer las comprobaciones, la estructura sería la siguiente:

declare	@Candidatos as table
		(
		  id int ,
		  nombre nvarchar(50) ,
		  nombreReferenciaPersonal nvarchar(50),
		  telReferenciaPersonal nvarchar(50) ,
		  nombreReferenciaLaboral nvarchar(50),
		  telReferenciaLaboral nvarchar(50)
		);

Insertamos unos datos de ejemplo

insert into @Candidatos
values 
 ( 1 , N'Marco', N'Pedro',  N'668-344', N'Junior', N'879-522'),
 ( 2 , N'Mirella', N'Cesar', N'806-788', N'Carla', N'356-990'),
 ( 3 , N'Juan', N'Bety', N'890-889', N'Sonia', N'887-999') ,
 ( 4 , N'Beto', N'Fidencio', N'803-344', N'Marcela', N'343-002') ,
 ( 5 , N'Joan', N'Lucas', N'718-009', N'Desire', N'126-039') ;

Para el caso simple de UNPIVOT, necesitamos extraer el nombre de los candidatos y todos los numeros a los que hay que llamar, mostrando cada numero de telefono como una fila, solo bastaría con esta query:

 select id, nombre, nro from @Candidatos c
unpivot (nro for numero in (telReferenciaPersonal, telReferenciaLaboral)) as upv;

El resultado:

id nombre nro
1 Marco 668-344
1 Marco 879-522
2 Mirella 806-788
2 Mirella 356-990
3 Juan 890-889
3 Juan 887-999
4 Beto 803-344
4 Beto 343-002
5 Joan 718-009
5 Joan 126-039

El problema que podria tener RRHH es que tiene todos los numeros de telefono pero no puede saber con anticipación el nombre de las referencias a las que esta llamando, y para no realizar consultas innecesariamente ineficientes y engorrosas con sub consultas, podemos hacer unpivot de una segunda columna. En principio armamos la siguiente query

select
	id,
	candidato,
	referencia,
	telefono
 from
	(
	  select
		c.id ,
		c.nombre candidato,
		c.nombreReferenciaPersonal  ,
		c.telReferenciaPersonal  ,
		c.nombreReferenciaLaboral  ,
		c.telReferenciaLaboral 
	  from
		@Candidatos c
	) as source unpivot ( referencia for nombres in ( nombreReferenciaPersonal, nombreReferenciaLaboral ) ) as upvReferencias
	unpivot ( telefono for nro in ( telReferenciaPersonal, telReferenciaLaboral ) ) as upvTelefonos

En parte, esto ya nos trae unpivoteado varias columnas, pero nos hace un cruce cartesiano entre todas las combinaciones posibles, en nuestro caso en particular, al tener 5 candidatos con dos posibles numeros a llamar, tenemos que tener 10 filas, pero al volver a unpivotear los nombres de referencia se crean otras 10 filas devolviendonos 20 en total, con combinaciones que no nos sirven realmente. Para solucionar esto podemos valernos de los alias en las columnas del mismo dominio, a los nombres de las referencias personales le llamamos referencia1 y a los laborales referencia2, lo importante aqui es que la primer parte de los alias sean iguales siendo diferenciados por un valor numérico incremental por cada columna extras que necesitemos unpivotear, lo mismo aplicamos para los numeros (si las columnas de nuestra tabla base ya están nombradas de esta manera, no hace falta utilizar los alias).

Luego con un pequeño “truco”, por así decirlo, agregamos un filtro where donde matcheamos los numeros que se van generando en cada columna, para ello nos valemos de la función RIGHT que corta el string de derecha a izquierda, y lo hacemos solamente en una posición

 select
	id,
	candidato,
	referencia,
	telefono
 from
	(
	  select
		c.id ,
		c.nombre candidato,
		c.nombreReferenciaPersonal referencia1 ,
		c.telReferenciaPersonal telefono1 ,
		c.nombreReferenciaLaboral referencia2 ,
		c.telReferenciaLaboral telefono2
	  from
		@Candidatos c
	) as source unpivot ( referencia for nombres in ( referencia1, referencia2 ) ) as upvReferencias
	unpivot ( telefono for nro in ( telefono1, telefono2 ) ) as upvTelefonos
 where
	right(nombres, 1) = right(nro, 1);

El resultado sería

id candidato referencia telefono
1 Marco Pedro 668-344
1 Marco Junior 879-522
2 Mirella Cesar 806-788
2 Mirella Carla 356-990
3 Juan Bety 890-889
3 Juan Sonia 887-999
4 Beto Fidencio 803-344
4 Beto Marcela 343-002
5 Joan Lucas 718-009
5 Joan Desire 126-039

Comentarios desde Facebook:

Sin Comentarios aun, puedes tú ser el primero en comentar!

Deja tu Comentario

Responder