viernes, 18 de febrero de 2011

Factorial de n usando una sentencia SQL simple.

Quizás alguna vez se han preguntado porque no existe una función de agregación PROD, que obtenga el producto de una columna numerica o expresión de una tabla, me parece que no, verdad?. Muy probablemente a la mayoria, nunca se le ha generado esa inquietud, porque de hecho, no tiene, a priori, demasiada utilidad en los sistemas reales. De todas formas, la idea de la nota es mostrarles que tan simple y elegante puede ser una solución usando solo una simple sentencia SELECT, independientemente si le encuentran alguna utilidad o no.

Como una breve introducción, voy a repasar las funciones de agregación, que son variadas. Las mas conocidas y usadas mas frecuentemente son:

SUM: Retorna la suma de una columna o expresión
AVG: Retorna el promedio de una columa o expresión
MIN: Retorna el valor mínimo
MAX: Retorna el valor máximo

Otras funciones, son las estadisticas, que suelo usar cuando necesito analizar tendencias y patrones, y son:

STDDEV : Retorna la desviación standard de una columna o expresión
VARIANCE : Retorna la varianza de una columna o expresión
MEDIAN : Retorna la mediana de una columna o expresión

existen muchas mas funciones de agregación para usar, ver detalle en el manual oficial para la versión de BD que necesiten, por ejemplo para 11g R2: SQL Reference 11.2 R2 (Funciones de Agregación)

En esta oportunidad, voy a mostrar como simular la función PROD usando algunas reglas matematicas simples, y por ultimo, usar dicha función para obtener el factorial de un número dado:

Para comenzar, voy a definir las dos funciones que voy a utilizar:

ln(n) = Retorna el logarimo natural de n

y su función inversa:

exp(n) = Retorna e elevado a la n

Ahora, partiendo de la siguiente propiedad matematica de los logaritmos:

ln(a) + Ln(b) = ln(a * b)

Elevando e con cada lado de la ecuación anterior:

exp(ln(a)+ln(b)) = exp(ln(a*b))

Dado que exp y ln son funciones inversas, entonces se anulan y nos queda a multiplicado por b:

exp(ln(a*b)) = a*b

En este punto, ya tenemos definida y explicada la regla. Ahora voy a mostrar un ejemplo de uso, para obtener el factorial:

La sentencia SQL para obtener el factorial de N tiene la siguiente forma:

select exp(sum(ln(rownum))) from dual
connect by rownum <= N ;


Un ejemplo usando como consola sqlplus:

rop@DESA10G> variable n number
rop@DESA10G> exec :n := 3;

Procedimiento PL/SQL terminado correctamente.


rop@DESA10G> select exp(sum(ln(rownum))) from dual
2 connect by rownum <= :n ;

EXP(SUM(LN(ROWNUM)))
--------------------
6

rop@DESA10G> exec :n := 6;

Procedimiento PL/SQL terminado correctamente.

rop@DESA10G> select exp(sum(ln(rownum)))
from dual
2 connect by rownum <= :n ;

EXP(SUM(LN(ROWNUM)))
--------------------
720

Como se ve, se puede obtener el factorial de cualquier número con una simple sentencia. También se podria usar para multiplicar las columnas de una tabla, multiplicar expresiones, etc.

3 comentarios:

  1. COMO PUEDO ASER UN FATORIAL EN SQL ES QNO LE ENTIENDO

    ResponderEliminar
  2. Tío... eres un puto máquina!! Estaba liado mirando a ver cómo podría multiplicar una columna en una tabla y me has resuelto el rebane de sesos... Con cierta edad se van olvidando estas propiedades y estaría bien refrescarlas de vez en cuando para resolver problemas de este tipo de manera 'quasy' inmediata.
    Mil gracias!!

    ResponderEliminar
  3. Mira que la teoría la sabía, pero que no se me ocurrió hasta que lo vi aquí.
    Muuuchas gracias!!!

    ResponderEliminar