SlideShare una empresa de Scribd logo
1 de 7
Descargar para leer sin conexión
Método SQL para Calcular el valor máximo de un
conjunto de columnas de una Tabla.
Utilización de subconsultas para realizar cálculos sobre “N” cantidad de
columnas sin utilizar sentencias CASE
Fecha: Mayo del 2013.
Versión: 1.0
Autor: Sebastián Rodríguez Robotham
e-mail: srodriguez@easybi.cl
Nombre Puntaje 1 Puntaje 2 Puntaje 3 Puntaje 4 Puntaje 5 Puntaje 6 Maxima Mínima
Nicolas 735 158 399 473 378 147 735 147
Cesar 578 252 557 410 441 504 578 252
Hector 578 NULL 168 NULL 189 714 714 168
Mario 578 105 168 105 189 714 714 105
Daniela 683 473 399 326 347 294 683 294
Jorge 105 672 672 735 693 305 735 105
Método SQL para Calcular el valor máximo de un conjunto de columnas en una Tabla
Sebastián Rodríguez Robotham. www.EasyBI.cl 2 | P a g e
Introducción.
Hay ocasiones en que debemos realizar cálculos que parecen simples en papel, sin embargo al
intentar hacer la consulta en SQL nos damos cuenta que son más complejas de lo que pensamos, o
que requieren de mucha codificación para llevarla a cabo.
El presente documento resuelve de forma elegante y escalable un problema común de SQL para
realizar cálculos de agrupación sobre columnas.
En la parte final del documento, hay un anexo que describe la solución completa del problema con
indicaciones especiales acerca de las sentencias UNION, UNION ALL y cálculo de las funciones de
agregación cuando existen valores nulos en los campos.
Problema.
Supongamos que contamos con un listado de clientes, y cada cliente tiene diversos puntajes
otorgados por un sistema de segmentación mensual, el requerimiento es calcular el puntaje
promedio y máximo de los últimos 6 meses, tal como lo muestra la siguiente figura:
Figura 1 – Listado de Puntajes de Clientes
Solución Clásica.
Primero generaremos una tabla con la estructura necesaria para almacenar la información base:
CREATE TABLE #TempRowToColumn ( Nombre VARCHAR(100)
,Puntaje_P1 INT
,Puntaje_P2 INT
,Puntaje_P3 INT
,Puntaje_P4 INT
,Puntaje_P5 INT
,Puntaje_P6 INT)
Luego, poblaremos la tabla con la información publicada en la Figura 1.
INSERT INTO #TempRowToColumn VALUES ('Nicolas',735,158,399,473,378,147),
('Cesar',578,252,557,410,441,504),
('Hector',578,NULL,168,NULL,189,714),
('Mario',578,105,168,105,189,714),
('Daniela',683,473,399,326,347,294),
Nombre Puntaje 1 Puntaje 2 Puntaje 3 Puntaje 4 Puntaje 5 Puntaje 6
Nicolas 735 158 399 473 378 147
Cesar 578 252 557 410 441 504
Hector 578 NULL 168 NULL 189 714
Mario 578 105 168 105 189 714
Daniela 683 473 399 326 347 294
Jorge 105 672 672 735 693 305
Método SQL para Calcular el valor máximo de un conjunto de columnas en una Tabla
Sebastián Rodríguez Robotham. www.EasyBI.cl 3 | P a g e
('Jorge',105,672,672,735,693,305)
Para calcular el promedio es bastante simple, ya que debemos sumar los 6 puntajes y dividirla en
6, sin embargo presenta un inconveniente, hay datos nulos que entregarán un resultado diferente
al que esperábamos inicialmente (los valores nulos hacen que el resultado final sea nulo en el
cliente “Héctor”), la figura 2 muestra el resultado de esta operación.
SELECT *
, (Puntaje_P1+ Puntaje_P2 + Puntaje_P3 +
Puntaje_P4 + Puntaje_P5 + Puntaje_P6) / 6 as Promedio
FROM #TempRowToColumn
Figura 2 – Calculo del Promedio
Y finalmente, si queremos calcular el valor máximo, tendremos que realizar una sentencia CASE
que evalúe cada alternativa, de la siguiente forma:
CASE WHEN Puntaje_P1 > Puntaje_P2 AND Puntaje_P1 > Puntaje_P3 AND
Puntaje_P1 > Puntaje_P4 AND Puntaje_P1 > Puntaje_P5 AND
Puntaje_P1 > Puntaje_P6 THEN Puntaje_P1
WHEN Puntaje_P2 > Puntaje_P3 AND Puntaje_P2 > Puntaje_P4 AND
Puntaje_P2 > Puntaje_P5 AND Puntaje_P2 > Puntaje_P6 THEN Puntaje_P2
WHEN Puntaje_P3 > Puntaje_P4 AND Puntaje_P3 > Puntaje_P5 AND
Puntaje_P3 > Puntaje_P6 THEN Puntaje_P3
WHEN Puntaje_P4 > Puntaje_P5 AND Puntaje_P4 > Puntaje_P6 THEN Puntaje_P4
WHEN Puntaje_P5 > Puntaje_P6 THEN Puntaje_P4
ELSE Puntaje_P6
END AS maximo
Figura 3 – Calculo del Promedio y Valor Máximo.
Nombre Puntaje 1 Puntaje 2 Puntaje 3 Puntaje 4 Puntaje 5 Puntaje 6 Promedio
Nicolas 735 158 399 473 378 147 381
Cesar 578 252 557 410 441 504 457
Hector 578 NULL 168 NULL 189 714 NULL
Mario 578 105 168 105 189 714 309
Daniela 683 473 399 326 347 294 420
Jorge 105 672 672 735 693 305 530
Nombre Puntaje 1 Puntaje 2 Puntaje 3 Puntaje 4 Puntaje 5 Puntaje 6 Promedio Maximo
Nicolas 735 158 399 473 378 147 381 735
Cesar 578 252 557 410 441 504 457 578
Hector 578 NULL 168 NULL 189 714 NULL 714
Mario 578 105 168 105 189 714 309 714
Daniela 683 473 399 326 347 294 420 683
Jorge 105 672 672 735 693 305 530 735
Método SQL para Calcular el valor máximo de un conjunto de columnas en una Tabla
Sebastián Rodríguez Robotham. www.EasyBI.cl 4 | P a g e
El problema de utilizar esta solución es que no es escalable, es decir cuando tenemos 10 o 20
columnas que comparar, la codificación se hace muy pesada y riesgosa, ya que es fácil cometer
errores en las comparaciones CASE.
Solución Óptima.
Para solucionar este tipo de requerimientos, lo que debemos hacer es convertir las columnas de
cada fila en una nueva subquery que podemos trabajar a nivel de la misma fila, y utilizar las
funciones de agrupamiento que provee SQL Server, a continuación se presenta la solución
propuesta.
SELECT T1.*
,(SELECT MAX(Puntaje)
FROM ( SELECT Puntaje_P1 AS Puntaje
UNION ALL SELECT Puntaje_P2
UNION ALL SELECT Puntaje_P3
UNION ALL SELECT Puntaje_P4
UNION ALL SELECT Puntaje_P5
UNION ALL SELECT Puntaje_P6) AliasTabla
) AS PuntajeMaximo
FROM #TempRowToColumn T1
Figura 4 – Resultado Máximo con SubQuery a Nivel de Fila.
Lo que hace esta consulta es bastante sencillo: crea una subconsulta con los valores de cada
columna, similar a la siguiente sentencia:
SELECT 1 AS Puntaje
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
Donde el resultado es una lista de números del uno al cinco, luego al utilizar esta sentencia como
subquery y aplicar una función de agregado, por ejemplo máximo, obtendremos el resultado
deseado (valor 5 como resultado de la función MAX):
Nombre Puntaje_P1 Puntaje_P2 Puntaje_P3 Puntaje_P4 Puntaje_P5 Puntaje_P6
Puntaje
Maximo
Nicolas 735 158 399 473 378 147 735
Cesar 578 252 557 410 441 504 578
Hector 578 NULL 168 NULL 189 714 714
Mario 578 105 168 105 189 714 714
Daniela 683 473 399 326 347 294 683
Jorge 105 672 672 735 693 305 735
Nueva
Columna
Método SQL para Calcular el valor máximo de un conjunto de columnas en una Tabla
Sebastián Rodríguez Robotham. www.EasyBI.cl 5 | P a g e
SELECT MAX(Puntaje)
FROM (
SELECT 1 AS Puntaje
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
) As Alias
El mismo concepto se aplica en la solución óptima, pero ahora en vez de utilizar valores
constantes, utilizamos los campos que provee la tabla #TempRowToColumn.
Rendimiento.
La siguiente figura muestra la comparación en rendimiento de ambas consultas, siendo la solución
tradicional ligeramente más eficiente que la solución propuesta en este documento, sin embargo
se observa que la diferencia es mínima.
Figura 5 – Comparación Plan de Ejecución: Consulta Tradicional vs Consulta Óptima.
Conclusiones Finales
Este método para resolver los requerimientos relacionados a funciones de agregación sobre
columnas es elegante en términos de codificación y fácilmente escalable, ya que permite incluir en
forma simple “N” columnas a la query, y el impacto en términos de posibles errores de digitación
es mínimo en comparación al método tradicional, por otro lado permite comprender fácilmente el
código implementado. Como desventaja podemos indicar que es ligeramente menos eficiente que
el método tradicional.
Método SQL para Calcular el valor máximo de un conjunto de columnas en una Tabla
Sebastián Rodríguez Robotham. www.EasyBI.cl 6 | P a g e
Anexo 1. Código de Ejemplo y Consideraciones en la cláusula UNION
A continuación se muestra el código a implementar para calcular los máximos, mínimos y
promedios de los clientes. Este ejemplo, además, pretende mostrar la diferencia que existe al
utilizar UNION, UNION ALL y AVG con valores NULL.
UNION vs UNION ALL
Como se muestra en la figura 6, el cliente “Mario” tiene valores repetidos (el valor 105 está 2
veces), por tanto al aplicar “UNION” considera solo un valor 105 y esto afecta el resultado del
promedio, en cambio cuando se aplica “UNION ALL” consideran todos los valores de las columnas,
aunque estos estén repetidos, a continuación se calcula manualmente esta fila:
Promedio con UNION : 578 + 105 + 168 + 189 + 714 = 1754 / 5 = 350 (Considera solo 5 valores)
Promedio con UNION ALL : 578 + 105 + 168 + 105 + 189 + 714 = 1859 / 6 = 309 (Valor correcto)
Función AVG vs Promedio Calculado Manualmente
Las columnas Promedio_01 calcula el promedio con AVG, mientras que Promedio_02 realiza la
suma de todas las columnas y divide en la cantidad de períodos. Como vemos en la figura 6, la
mayoría de los casos son idénticos, con excepción del cliente “Héctor”, dado que esta fila tiene
valores NULL. A diferencia del error por UNION, en este caso es necesario especificar el
comportamiento esperado con los puntajes, ¿se promedia con los puntajes reales o se promedia
por todos los períodos?, ¿Qué valor asignar en caso que no exista medición para ese cliente?, por
tanto en este caso no existe error de cálculo, sino que falta en la definición del criterio, por ese
motivo se presentan ambos resultados como válido en este ejemplo.
SELECT T1.*
,(SELECT MAX(Nota)
FROM (SELECT Puntaje_P1 AS Nota
UNION ALL SELECT Puntaje_P2
UNION ALL SELECT Puntaje_P3
UNION ALL SELECT Puntaje_P4
UNION ALL SELECT Puntaje_P5
UNION ALL SELECT Puntaje_P6 ) Alias) AS PuntajeMaximo
,(SELECT MIN(Nota)
FROM (SELECT Puntaje_P1 AS Nota
UNION ALL SELECT Puntaje_P2
UNION ALL SELECT Puntaje_P3
UNION ALL SELECT Puntaje_P4
UNION ALL SELECT Puntaje_P5
UNION ALL SELECT Puntaje_P6 ) Alias) AS PuntajeMinimo
,(SELECT AVG(Nota)
FROM (SELECT Puntaje_P1 AS Nota
UNION ALL SELECT Puntaje_P2
UNION ALL SELECT Puntaje_P3
UNION ALL SELECT Puntaje_P4
UNION ALL SELECT Puntaje_P5
UNION ALL SELECT Puntaje_P6 ) Alias) AS Promedio_01_UnionAll
Método SQL para Calcular el valor máximo de un conjunto de columnas en una Tabla
Sebastián Rodríguez Robotham. www.EasyBI.cl 7 | P a g e
,(SELECT SUM(Nota)
FROM (SELECT Puntaje_P1 AS Nota
UNION ALL SELECT Puntaje_P2
UNION ALL SELECT Puntaje_P3
UNION ALL SELECT Puntaje_P4
UNION ALL SELECT Puntaje_P5
UNION ALL SELECT Puntaje_P6 ) Alias) / 6 AS Promedio_02_UnionAll
,(SELECT AVG(Nota)
FROM (SELECT Puntaje_P1 AS Nota
UNION SELECT Puntaje_P2
UNION SELECT Puntaje_P3
UNION SELECT Puntaje_P4
UNION SELECT Puntaje_P5
UNION SELECT Puntaje_P6 ) Alias) AS Promedio_01_UnionSimple
,(SELECT SUM(Nota)
FROM (SELECT Puntaje_P1 AS Nota
UNION SELECT Puntaje_P2
UNION SELECT Puntaje_P3
UNION SELECT Puntaje_P4
UNION SELECT Puntaje_P5
UNION SELECT Puntaje_P6 ) Alias) / 6 AS Promedio_02_UnionSimple
FROM #TempRowToColumn T1
Figura 6 – Resultados de Query Final.
Nombre
Puntaje
_P1
Puntaje
_P2
Puntaje
_P3
Puntaje
_P4
Puntaje
_P5
Puntaje
_P6
Puntaje
Maximo
Puntaje
Minimo
Promedio_01
_UnionAll
Promedio_02
_UnionAll
Promedio_01_
UnionSimple
Promedio_02_
UnionSimple
Nicolas 735 158 399 473 378 147 735 147 381 381 381 381
Cesar 578 252 557 410 441 504 578 252 457 457 457 457
Hector 578 NULL 168 NULL 189 714 714 168 412 274 412 274
Mario 578 105 168 105 189 714 714 105 309 309 350 292
Daniela 683 473 399 326 347 294 683 294 420 420 420 420
Jorge 105 672 672 735 693 305 735 105 530 530 502 418
Cálculo Erróneo por Union Simple (considera solo una instancia del valor)
Diferencia de cálculo por valores NULL

Más contenido relacionado

La actualidad más candente (8)

Manual Code::Blocks lenguaje C++
Manual Code::Blocks lenguaje C++Manual Code::Blocks lenguaje C++
Manual Code::Blocks lenguaje C++
 
CCNA Discovery 4.0 Examen Capítulo I Examen 3 (Respuestas o Solucionario)
CCNA Discovery 4.0 Examen Capítulo I Examen 3 (Respuestas o Solucionario)CCNA Discovery 4.0 Examen Capítulo I Examen 3 (Respuestas o Solucionario)
CCNA Discovery 4.0 Examen Capítulo I Examen 3 (Respuestas o Solucionario)
 
Ejercicios de-subneteo-14
Ejercicios de-subneteo-14Ejercicios de-subneteo-14
Ejercicios de-subneteo-14
 
9.1.4.9 lab subnetting network topologies
9.1.4.9 lab   subnetting network topologies9.1.4.9 lab   subnetting network topologies
9.1.4.9 lab subnetting network topologies
 
Red telematica-etapa 3
Red telematica-etapa 3Red telematica-etapa 3
Red telematica-etapa 3
 
WebSockets
WebSocketsWebSockets
WebSockets
 
Como realizar una red lan básica con packet tracer
Como realizar una red lan básica con packet tracerComo realizar una red lan básica con packet tracer
Como realizar una red lan básica con packet tracer
 
Subredes
SubredesSubredes
Subredes
 

Similar a Método SQL para Calcular el valor máximo de un conjunto de columnas de una Tabla

IntroduccióN Al Control De La ProduccióN
IntroduccióN Al Control De La ProduccióNIntroduccióN Al Control De La ProduccióN
IntroduccióN Al Control De La ProduccióN
adfst
 
IntroduccióN Al Control De La ProduccióN
IntroduccióN Al Control De La ProduccióNIntroduccióN Al Control De La ProduccióN
IntroduccióN Al Control De La ProduccióN
guest5e1760b
 
IntroduccióN Al Control De La ProduccióN
IntroduccióN Al Control De La ProduccióNIntroduccióN Al Control De La ProduccióN
IntroduccióN Al Control De La ProduccióN
guest5e1760b
 
Diseño algoritmosoo sentenciascondicionales
Diseño algoritmosoo sentenciascondicionalesDiseño algoritmosoo sentenciascondicionales
Diseño algoritmosoo sentenciascondicionales
María Luisa Velasco
 
Proceso Estadistico Peter Meletz
Proceso Estadistico Peter MeletzProceso Estadistico Peter Meletz
Proceso Estadistico Peter Meletz
Piter Meletz
 

Similar a Método SQL para Calcular el valor máximo de un conjunto de columnas de una Tabla (20)

Datos agrupados 01
Datos agrupados 01Datos agrupados 01
Datos agrupados 01
 
Datos agrupados utt 01
Datos agrupados utt 01Datos agrupados utt 01
Datos agrupados utt 01
 
Excel novenos.pptx
Excel novenos.pptxExcel novenos.pptx
Excel novenos.pptx
 
Manual software
Manual softwareManual software
Manual software
 
1 simulacion introduccion
1 simulacion introduccion1 simulacion introduccion
1 simulacion introduccion
 
Curso de PLSQL Oracle 11g
Curso de PLSQL Oracle 11gCurso de PLSQL Oracle 11g
Curso de PLSQL Oracle 11g
 
IntroduccióN Al Control De La ProduccióN
IntroduccióN Al Control De La ProduccióNIntroduccióN Al Control De La ProduccióN
IntroduccióN Al Control De La ProduccióN
 
IntroduccióN Al Control De La ProduccióN
IntroduccióN Al Control De La ProduccióNIntroduccióN Al Control De La ProduccióN
IntroduccióN Al Control De La ProduccióN
 
IntroduccióN Al Control De La ProduccióN
IntroduccióN Al Control De La ProduccióNIntroduccióN Al Control De La ProduccióN
IntroduccióN Al Control De La ProduccióN
 
recuperacion excel.pdf
recuperacion excel.pdfrecuperacion excel.pdf
recuperacion excel.pdf
 
System Simulation with Excel (Part 2)
System Simulation with Excel (Part 2)System Simulation with Excel (Part 2)
System Simulation with Excel (Part 2)
 
Diseño algoritmosoo sentenciascondicionales
Diseño algoritmosoo sentenciascondicionalesDiseño algoritmosoo sentenciascondicionales
Diseño algoritmosoo sentenciascondicionales
 
Distribución de los recursos
Distribución de los recursosDistribución de los recursos
Distribución de los recursos
 
Proceso Estadistico Peter Meletz
Proceso Estadistico Peter MeletzProceso Estadistico Peter Meletz
Proceso Estadistico Peter Meletz
 
Computacion
ComputacionComputacion
Computacion
 
Software omegaup
Software omegaupSoftware omegaup
Software omegaup
 
Ensayo control de calidad
Ensayo control de calidadEnsayo control de calidad
Ensayo control de calidad
 
Software omegaup
Software omegaupSoftware omegaup
Software omegaup
 
Guía de Extraordinario RicardoJ
Guía de Extraordinario RicardoJGuía de Extraordinario RicardoJ
Guía de Extraordinario RicardoJ
 
Reporte del DATA SET "Balance scale" con WEKA
Reporte del DATA SET "Balance scale" con WEKAReporte del DATA SET "Balance scale" con WEKA
Reporte del DATA SET "Balance scale" con WEKA
 

Más de Sebastian Rodriguez Robotham

Estrategia para la Implementación y Administración Inteligente de DataWarehouse
Estrategia para la Implementación y Administración Inteligente de DataWarehouseEstrategia para la Implementación y Administración Inteligente de DataWarehouse
Estrategia para la Implementación y Administración Inteligente de DataWarehouse
Sebastian Rodriguez Robotham
 

Más de Sebastian Rodriguez Robotham (8)

Desafíos No Tecnológicos para implementar Big Data
Desafíos No Tecnológicos para implementar Big DataDesafíos No Tecnológicos para implementar Big Data
Desafíos No Tecnológicos para implementar Big Data
 
La colaboración y cooperación como estrategias en la educación superior
La colaboración y cooperación como estrategias en la educación superiorLa colaboración y cooperación como estrategias en la educación superior
La colaboración y cooperación como estrategias en la educación superior
 
Evolucion y desafios del sistema de aseguramiento de la calidad en la educaci...
Evolucion y desafios del sistema de aseguramiento de la calidad en la educaci...Evolucion y desafios del sistema de aseguramiento de la calidad en la educaci...
Evolucion y desafios del sistema de aseguramiento de la calidad en la educaci...
 
POC SQL 2014
POC SQL 2014POC SQL 2014
POC SQL 2014
 
Diseño eficiente de un cubo para resolver problemas en las áreas de negocio
Diseño eficiente de un cubo para resolver problemas en las áreas de negocioDiseño eficiente de un cubo para resolver problemas en las áreas de negocio
Diseño eficiente de un cubo para resolver problemas en las áreas de negocio
 
Método SQL para comprimir archivos de carga de datos
Método SQL para comprimir archivos de carga de datosMétodo SQL para comprimir archivos de carga de datos
Método SQL para comprimir archivos de carga de datos
 
Estrategia para la Implementación y Administración Inteligente de DataWarehouse
Estrategia para la Implementación y Administración Inteligente de DataWarehouseEstrategia para la Implementación y Administración Inteligente de DataWarehouse
Estrategia para la Implementación y Administración Inteligente de DataWarehouse
 
Introducción a DataWarehouse e Inteligencia de Negocios
Introducción a DataWarehouse e Inteligencia de NegociosIntroducción a DataWarehouse e Inteligencia de Negocios
Introducción a DataWarehouse e Inteligencia de Negocios
 

Último

redes informaticas en una oficina administrativa
redes informaticas en una oficina administrativaredes informaticas en una oficina administrativa
redes informaticas en una oficina administrativa
nicho110
 

Último (14)

presentacion_desamblado_de_una_computadora_base_a_las_normas_de_seguridad.pdf
presentacion_desamblado_de_una_computadora_base_a_las_normas_de_seguridad.pdfpresentacion_desamblado_de_una_computadora_base_a_las_normas_de_seguridad.pdf
presentacion_desamblado_de_una_computadora_base_a_las_normas_de_seguridad.pdf
 
Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21
 
presentación del desensamble y ensamble del equipo de computo en base a las n...
presentación del desensamble y ensamble del equipo de computo en base a las n...presentación del desensamble y ensamble del equipo de computo en base a las n...
presentación del desensamble y ensamble del equipo de computo en base a las n...
 
redes informaticas en una oficina administrativa
redes informaticas en una oficina administrativaredes informaticas en una oficina administrativa
redes informaticas en una oficina administrativa
 
How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estos
 
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxEVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
 
Buenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptxBuenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptx
 
Guia Basica para bachillerato de Circuitos Basicos
Guia Basica para bachillerato de Circuitos BasicosGuia Basica para bachillerato de Circuitos Basicos
Guia Basica para bachillerato de Circuitos Basicos
 
investigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXIinvestigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXI
 
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
 
infor expo AVANCES TECNOLOGICOS DEL SIGLO 21.pptx
infor expo AVANCES TECNOLOGICOS DEL SIGLO 21.pptxinfor expo AVANCES TECNOLOGICOS DEL SIGLO 21.pptx
infor expo AVANCES TECNOLOGICOS DEL SIGLO 21.pptx
 
Generaciones de las Computadoras..pdf...
Generaciones de las Computadoras..pdf...Generaciones de las Computadoras..pdf...
Generaciones de las Computadoras..pdf...
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvana
 

Método SQL para Calcular el valor máximo de un conjunto de columnas de una Tabla

  • 1. Método SQL para Calcular el valor máximo de un conjunto de columnas de una Tabla. Utilización de subconsultas para realizar cálculos sobre “N” cantidad de columnas sin utilizar sentencias CASE Fecha: Mayo del 2013. Versión: 1.0 Autor: Sebastián Rodríguez Robotham e-mail: srodriguez@easybi.cl Nombre Puntaje 1 Puntaje 2 Puntaje 3 Puntaje 4 Puntaje 5 Puntaje 6 Maxima Mínima Nicolas 735 158 399 473 378 147 735 147 Cesar 578 252 557 410 441 504 578 252 Hector 578 NULL 168 NULL 189 714 714 168 Mario 578 105 168 105 189 714 714 105 Daniela 683 473 399 326 347 294 683 294 Jorge 105 672 672 735 693 305 735 105
  • 2. Método SQL para Calcular el valor máximo de un conjunto de columnas en una Tabla Sebastián Rodríguez Robotham. www.EasyBI.cl 2 | P a g e Introducción. Hay ocasiones en que debemos realizar cálculos que parecen simples en papel, sin embargo al intentar hacer la consulta en SQL nos damos cuenta que son más complejas de lo que pensamos, o que requieren de mucha codificación para llevarla a cabo. El presente documento resuelve de forma elegante y escalable un problema común de SQL para realizar cálculos de agrupación sobre columnas. En la parte final del documento, hay un anexo que describe la solución completa del problema con indicaciones especiales acerca de las sentencias UNION, UNION ALL y cálculo de las funciones de agregación cuando existen valores nulos en los campos. Problema. Supongamos que contamos con un listado de clientes, y cada cliente tiene diversos puntajes otorgados por un sistema de segmentación mensual, el requerimiento es calcular el puntaje promedio y máximo de los últimos 6 meses, tal como lo muestra la siguiente figura: Figura 1 – Listado de Puntajes de Clientes Solución Clásica. Primero generaremos una tabla con la estructura necesaria para almacenar la información base: CREATE TABLE #TempRowToColumn ( Nombre VARCHAR(100) ,Puntaje_P1 INT ,Puntaje_P2 INT ,Puntaje_P3 INT ,Puntaje_P4 INT ,Puntaje_P5 INT ,Puntaje_P6 INT) Luego, poblaremos la tabla con la información publicada en la Figura 1. INSERT INTO #TempRowToColumn VALUES ('Nicolas',735,158,399,473,378,147), ('Cesar',578,252,557,410,441,504), ('Hector',578,NULL,168,NULL,189,714), ('Mario',578,105,168,105,189,714), ('Daniela',683,473,399,326,347,294), Nombre Puntaje 1 Puntaje 2 Puntaje 3 Puntaje 4 Puntaje 5 Puntaje 6 Nicolas 735 158 399 473 378 147 Cesar 578 252 557 410 441 504 Hector 578 NULL 168 NULL 189 714 Mario 578 105 168 105 189 714 Daniela 683 473 399 326 347 294 Jorge 105 672 672 735 693 305
  • 3. Método SQL para Calcular el valor máximo de un conjunto de columnas en una Tabla Sebastián Rodríguez Robotham. www.EasyBI.cl 3 | P a g e ('Jorge',105,672,672,735,693,305) Para calcular el promedio es bastante simple, ya que debemos sumar los 6 puntajes y dividirla en 6, sin embargo presenta un inconveniente, hay datos nulos que entregarán un resultado diferente al que esperábamos inicialmente (los valores nulos hacen que el resultado final sea nulo en el cliente “Héctor”), la figura 2 muestra el resultado de esta operación. SELECT * , (Puntaje_P1+ Puntaje_P2 + Puntaje_P3 + Puntaje_P4 + Puntaje_P5 + Puntaje_P6) / 6 as Promedio FROM #TempRowToColumn Figura 2 – Calculo del Promedio Y finalmente, si queremos calcular el valor máximo, tendremos que realizar una sentencia CASE que evalúe cada alternativa, de la siguiente forma: CASE WHEN Puntaje_P1 > Puntaje_P2 AND Puntaje_P1 > Puntaje_P3 AND Puntaje_P1 > Puntaje_P4 AND Puntaje_P1 > Puntaje_P5 AND Puntaje_P1 > Puntaje_P6 THEN Puntaje_P1 WHEN Puntaje_P2 > Puntaje_P3 AND Puntaje_P2 > Puntaje_P4 AND Puntaje_P2 > Puntaje_P5 AND Puntaje_P2 > Puntaje_P6 THEN Puntaje_P2 WHEN Puntaje_P3 > Puntaje_P4 AND Puntaje_P3 > Puntaje_P5 AND Puntaje_P3 > Puntaje_P6 THEN Puntaje_P3 WHEN Puntaje_P4 > Puntaje_P5 AND Puntaje_P4 > Puntaje_P6 THEN Puntaje_P4 WHEN Puntaje_P5 > Puntaje_P6 THEN Puntaje_P4 ELSE Puntaje_P6 END AS maximo Figura 3 – Calculo del Promedio y Valor Máximo. Nombre Puntaje 1 Puntaje 2 Puntaje 3 Puntaje 4 Puntaje 5 Puntaje 6 Promedio Nicolas 735 158 399 473 378 147 381 Cesar 578 252 557 410 441 504 457 Hector 578 NULL 168 NULL 189 714 NULL Mario 578 105 168 105 189 714 309 Daniela 683 473 399 326 347 294 420 Jorge 105 672 672 735 693 305 530 Nombre Puntaje 1 Puntaje 2 Puntaje 3 Puntaje 4 Puntaje 5 Puntaje 6 Promedio Maximo Nicolas 735 158 399 473 378 147 381 735 Cesar 578 252 557 410 441 504 457 578 Hector 578 NULL 168 NULL 189 714 NULL 714 Mario 578 105 168 105 189 714 309 714 Daniela 683 473 399 326 347 294 420 683 Jorge 105 672 672 735 693 305 530 735
  • 4. Método SQL para Calcular el valor máximo de un conjunto de columnas en una Tabla Sebastián Rodríguez Robotham. www.EasyBI.cl 4 | P a g e El problema de utilizar esta solución es que no es escalable, es decir cuando tenemos 10 o 20 columnas que comparar, la codificación se hace muy pesada y riesgosa, ya que es fácil cometer errores en las comparaciones CASE. Solución Óptima. Para solucionar este tipo de requerimientos, lo que debemos hacer es convertir las columnas de cada fila en una nueva subquery que podemos trabajar a nivel de la misma fila, y utilizar las funciones de agrupamiento que provee SQL Server, a continuación se presenta la solución propuesta. SELECT T1.* ,(SELECT MAX(Puntaje) FROM ( SELECT Puntaje_P1 AS Puntaje UNION ALL SELECT Puntaje_P2 UNION ALL SELECT Puntaje_P3 UNION ALL SELECT Puntaje_P4 UNION ALL SELECT Puntaje_P5 UNION ALL SELECT Puntaje_P6) AliasTabla ) AS PuntajeMaximo FROM #TempRowToColumn T1 Figura 4 – Resultado Máximo con SubQuery a Nivel de Fila. Lo que hace esta consulta es bastante sencillo: crea una subconsulta con los valores de cada columna, similar a la siguiente sentencia: SELECT 1 AS Puntaje UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 Donde el resultado es una lista de números del uno al cinco, luego al utilizar esta sentencia como subquery y aplicar una función de agregado, por ejemplo máximo, obtendremos el resultado deseado (valor 5 como resultado de la función MAX): Nombre Puntaje_P1 Puntaje_P2 Puntaje_P3 Puntaje_P4 Puntaje_P5 Puntaje_P6 Puntaje Maximo Nicolas 735 158 399 473 378 147 735 Cesar 578 252 557 410 441 504 578 Hector 578 NULL 168 NULL 189 714 714 Mario 578 105 168 105 189 714 714 Daniela 683 473 399 326 347 294 683 Jorge 105 672 672 735 693 305 735 Nueva Columna
  • 5. Método SQL para Calcular el valor máximo de un conjunto de columnas en una Tabla Sebastián Rodríguez Robotham. www.EasyBI.cl 5 | P a g e SELECT MAX(Puntaje) FROM ( SELECT 1 AS Puntaje UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 ) As Alias El mismo concepto se aplica en la solución óptima, pero ahora en vez de utilizar valores constantes, utilizamos los campos que provee la tabla #TempRowToColumn. Rendimiento. La siguiente figura muestra la comparación en rendimiento de ambas consultas, siendo la solución tradicional ligeramente más eficiente que la solución propuesta en este documento, sin embargo se observa que la diferencia es mínima. Figura 5 – Comparación Plan de Ejecución: Consulta Tradicional vs Consulta Óptima. Conclusiones Finales Este método para resolver los requerimientos relacionados a funciones de agregación sobre columnas es elegante en términos de codificación y fácilmente escalable, ya que permite incluir en forma simple “N” columnas a la query, y el impacto en términos de posibles errores de digitación es mínimo en comparación al método tradicional, por otro lado permite comprender fácilmente el código implementado. Como desventaja podemos indicar que es ligeramente menos eficiente que el método tradicional.
  • 6. Método SQL para Calcular el valor máximo de un conjunto de columnas en una Tabla Sebastián Rodríguez Robotham. www.EasyBI.cl 6 | P a g e Anexo 1. Código de Ejemplo y Consideraciones en la cláusula UNION A continuación se muestra el código a implementar para calcular los máximos, mínimos y promedios de los clientes. Este ejemplo, además, pretende mostrar la diferencia que existe al utilizar UNION, UNION ALL y AVG con valores NULL. UNION vs UNION ALL Como se muestra en la figura 6, el cliente “Mario” tiene valores repetidos (el valor 105 está 2 veces), por tanto al aplicar “UNION” considera solo un valor 105 y esto afecta el resultado del promedio, en cambio cuando se aplica “UNION ALL” consideran todos los valores de las columnas, aunque estos estén repetidos, a continuación se calcula manualmente esta fila: Promedio con UNION : 578 + 105 + 168 + 189 + 714 = 1754 / 5 = 350 (Considera solo 5 valores) Promedio con UNION ALL : 578 + 105 + 168 + 105 + 189 + 714 = 1859 / 6 = 309 (Valor correcto) Función AVG vs Promedio Calculado Manualmente Las columnas Promedio_01 calcula el promedio con AVG, mientras que Promedio_02 realiza la suma de todas las columnas y divide en la cantidad de períodos. Como vemos en la figura 6, la mayoría de los casos son idénticos, con excepción del cliente “Héctor”, dado que esta fila tiene valores NULL. A diferencia del error por UNION, en este caso es necesario especificar el comportamiento esperado con los puntajes, ¿se promedia con los puntajes reales o se promedia por todos los períodos?, ¿Qué valor asignar en caso que no exista medición para ese cliente?, por tanto en este caso no existe error de cálculo, sino que falta en la definición del criterio, por ese motivo se presentan ambos resultados como válido en este ejemplo. SELECT T1.* ,(SELECT MAX(Nota) FROM (SELECT Puntaje_P1 AS Nota UNION ALL SELECT Puntaje_P2 UNION ALL SELECT Puntaje_P3 UNION ALL SELECT Puntaje_P4 UNION ALL SELECT Puntaje_P5 UNION ALL SELECT Puntaje_P6 ) Alias) AS PuntajeMaximo ,(SELECT MIN(Nota) FROM (SELECT Puntaje_P1 AS Nota UNION ALL SELECT Puntaje_P2 UNION ALL SELECT Puntaje_P3 UNION ALL SELECT Puntaje_P4 UNION ALL SELECT Puntaje_P5 UNION ALL SELECT Puntaje_P6 ) Alias) AS PuntajeMinimo ,(SELECT AVG(Nota) FROM (SELECT Puntaje_P1 AS Nota UNION ALL SELECT Puntaje_P2 UNION ALL SELECT Puntaje_P3 UNION ALL SELECT Puntaje_P4 UNION ALL SELECT Puntaje_P5 UNION ALL SELECT Puntaje_P6 ) Alias) AS Promedio_01_UnionAll
  • 7. Método SQL para Calcular el valor máximo de un conjunto de columnas en una Tabla Sebastián Rodríguez Robotham. www.EasyBI.cl 7 | P a g e ,(SELECT SUM(Nota) FROM (SELECT Puntaje_P1 AS Nota UNION ALL SELECT Puntaje_P2 UNION ALL SELECT Puntaje_P3 UNION ALL SELECT Puntaje_P4 UNION ALL SELECT Puntaje_P5 UNION ALL SELECT Puntaje_P6 ) Alias) / 6 AS Promedio_02_UnionAll ,(SELECT AVG(Nota) FROM (SELECT Puntaje_P1 AS Nota UNION SELECT Puntaje_P2 UNION SELECT Puntaje_P3 UNION SELECT Puntaje_P4 UNION SELECT Puntaje_P5 UNION SELECT Puntaje_P6 ) Alias) AS Promedio_01_UnionSimple ,(SELECT SUM(Nota) FROM (SELECT Puntaje_P1 AS Nota UNION SELECT Puntaje_P2 UNION SELECT Puntaje_P3 UNION SELECT Puntaje_P4 UNION SELECT Puntaje_P5 UNION SELECT Puntaje_P6 ) Alias) / 6 AS Promedio_02_UnionSimple FROM #TempRowToColumn T1 Figura 6 – Resultados de Query Final. Nombre Puntaje _P1 Puntaje _P2 Puntaje _P3 Puntaje _P4 Puntaje _P5 Puntaje _P6 Puntaje Maximo Puntaje Minimo Promedio_01 _UnionAll Promedio_02 _UnionAll Promedio_01_ UnionSimple Promedio_02_ UnionSimple Nicolas 735 158 399 473 378 147 735 147 381 381 381 381 Cesar 578 252 557 410 441 504 578 252 457 457 457 457 Hector 578 NULL 168 NULL 189 714 714 168 412 274 412 274 Mario 578 105 168 105 189 714 714 105 309 309 350 292 Daniela 683 473 399 326 347 294 683 294 420 420 420 420 Jorge 105 672 672 735 693 305 735 105 530 530 502 418 Cálculo Erróneo por Union Simple (considera solo una instancia del valor) Diferencia de cálculo por valores NULL