Mysql: Funciones de agregación y de Control de Flujo
Posted on November 8th, 2007 in Artículos, Programación |
Mysql como otros manejadores de base de datos nos ofrecen muchas herramientas y funciones que combinados nos dan gran flexibilidad y dinamismo en la manipulación de datos.
Este pequeño ejemplo nos permitirá usar dos herramientas, las funciones de agregación y las funciones condicionales, los que nos permitirá filtrar datos de una consulta agregada. Lo que vamos a obtener es el valor máximo de una serie de datos basándonos en una o más reglas.
Pongamos por ejemplo el anterior conjunto de datos. Representa una serie de tareas (A, B, C y D, definidas en la columna nombre) que constan de varios pasos (enumerados en la columna paso) para ser completadas. Cada tarea tiene diferente números de pasos y cada paso representa un porcentaje diferente de terminación.
El valor porcentual acumulado de la tarea es representado en el campo valor. Podemos ver que la tarea D tiene 4 pasos, y al completarse cada paso se lleva terminado en un 20, 40, 65 y 100% respectivamente.
Marcamos en el campo bandera los pasos hemos terminado. Una vez terminado un paso marcamos la bandera con uno por lo que sabremos siempre en que paso estamos. Podemos ver en los datos de ejemplo que la tarea A esta en el paso 2 con 34% de terminación.
Ahora, lo que queremos obtener en una sola consulta, es el porcentaje en el que todas las tareas se encuentran. Que seria el siguiente resultado.
El primer paso es agregar todos los resultados. Lo que nos permitirá empezar a ejecutar operaciones sobre los datos.
select * from tabla group by nombre
Una primera consulta rápida podría ser:
select nombre, max(valor) from tabla where bandera=1 group by nombre
Sin embargo esta consulta no nos va a funcionar, por que va a eliminar de la selección todos los resultados con banderas diferentes a 1, y si tenemos tareas como C en donde ninguna tarea esta terminada, estas tareas serán descartadas ya que los valores serán descartados. Podemos observarlo en la siguiente tabla:
select nombre, valor from tabla where bandera=1
Y usando:
select nombre, max(valor) from tabla group by nombre
Simplemente nos regresa los valores máximos de todas las tareas (100)
Tendremos que usar una condición en la expresión de las columnas para definir que solo tome en cuenta los valores de los pasos que ya fueron completados.
La función if esta definida como:
IF(expr1,expr2,expr3)
En donde la expr1 es evaluada, y si es verdadera regresa la expr2, si es falsa regresa la expr3.
Entonces podemos decirle que evalué la columna bandera, y que si esta es 1, entonces nos regrese el valor original, y si es falso, regrese nulo, o 0, ya que es un valor que no consideraremos:
if(bandera=1,valor,0)
Lo que ejecutado sin la agrupación nos regresa lo siguiente:
select nombre, if(bandera=1,valor,0) from tabla
Podemos apreciar que de esta forma, ya fácilmente podemos obtener el valor máximo usando la función max, ya que han sido eliminados los valores de los pasos no completados
select nombre, max(if(bandera=1,valor,0)) from tabla
group by nombre
Lo que nos regresa los valores que deseamos.
Este es un ejemplo de las muchas cosas que se pueden hacer mezclando las diversas funciones que nos proporciona mysql.
Popularidad: 42%

