sqlpostgresqlexplogarithm

EXP y LN en SQL: exponencial, logaritmo natural y medias geometricas

Como EXP y LN calculan e^x y el logaritmo natural, por que el par log/exp sirve para medias geometricas y tasas de crecimiento, y por que LN(0) falla.

3 min de lecturaReferencesql · postgresql · exp · logarithm · statistics · clickhouse

EXP eleva el numero de Euler e a una potencia, y LN toma el logaritmo natural en base e. Son funciones inversas entre si, y esa pareja es justo lo que convierte la multiplicacion en suma, dejando limpios los calculos de medias geometricas y tasas de crecimiento.

Que calculan EXP y LN

EXP(x) devuelve e^x, donde e vale aproximadamente 2.718281828. LN(x) es la inversa: responde a "a que potencia debo elevar e para obtener x".

SELECT
  EXP(1)        AS e,        -- 2.7182818...
  EXP(0)        AS one,      -- 1
  LN(EXP(1))    AS back,     -- 1
  LN(1)         AS zero;     -- 0

Propiedades clave en las que apoyarse:

  • EXP y LN se deshacen mutuamente: LN(EXP(x)) = x y EXP(LN(x)) = x para x > 0.
  • El logaritmo convierte un producto en una suma: LN(a * b) = LN(a) + LN(b).
  • El resultado en PostgreSQL es double precision, asi que espera pequenos errores de redondeo como 0.9999999998.

Media geometrica con exp(avg(ln))

Multiplicar muchos numeros de forma directa desborda casi cualquier tipo enseguida. El truco exp(avg(ln(x))) calcula la media geometrica sin salir de un rango seguro: tomamos logaritmos, los promediamos en el sentido aritmetico habitual y volvemos con la exponencial.

SELECT
  dept,
  EXP(AVG(LN(salary))) AS geo_mean_salary
FROM employees
WHERE salary > 0
GROUP BY dept
ORDER BY geo_mean_salary DESC;

La media geometrica resiste mejor los valores atipicos que la aritmetica, por eso se prefiere para salarios, precios y ratios. El mismo enfoque da un tamano de pedido tipico por pais:

SELECT
  u.country,
  EXP(AVG(LN(o.amount))) AS typical_order
FROM orders o
JOIN users u ON u.id = o.user_id
WHERE o.amount > 0
GROUP BY u.country;

Tasas de crecimiento y capitalizacion continua

La diferencia de logaritmos es el rendimiento logaritmico, la tasa de crecimiento continua entre dos valores. LN(new / old) da una cantidad que puedes sumar entre periodos, y EXP de la suma recupera el multiplicador total.

WITH monthly AS (
  SELECT
    date_trunc('month', created_at) AS m,
    SUM(amount)                     AS revenue
  FROM orders
  WHERE status = 'paid'
  GROUP BY 1
)
SELECT
  m,
  revenue,
  LN(revenue / LAG(revenue) OVER (ORDER BY m)) AS log_growth
FROM monthly
ORDER BY m;

Suma todos los valores de log_growth y aplica EXP a la suma para obtener el multiplicador de crecimiento total de todo el periodo, aunque las cifras mensuales hayan oscilado.

Trampa: LN(0) y LN de negativos

LN solo esta definido para numeros estrictamente positivos. LN(0) tiende a menos infinito y lanza un error en PostgreSQL, mientras que LN de un numero negativo no esta definido en absoluto.

SELECT LN(0);    -- ERROR: cannot take logarithm of zero
SELECT LN(-5);   -- ERROR: cannot take logarithm of a negative number

Protegete con un filtro o con NULLIF para que un solo cero no tumbe toda la agregacion:

SELECT
  dept,
  EXP(AVG(LN(NULLIF(salary, 0)))) AS geo_mean
FROM employees
GROUP BY dept;

Cuidado: los dialectos divergen. PostgreSQL y Oracle lanzan un error con LN(0), mientras que MySQL devuelve NULL tanto para LN(0) como para LN(-1). ClickHouse va mas alla y entrega -inf o nan sin error alguno. Nunca confies en el comportamiento por defecto; limpia siempre la entrada primero.

Cambio de base y pareja con LOG

El logaritmo natural permite construir un logaritmo en cualquier base con la formula LN(x) / LN(b). Ese es el mismo resultado que el LOG(b, x) incorporado en PostgreSQL.

SELECT
  LN(8) / LN(2)  AS log2_via_ln,   -- 3
  LOG(2, 8)      AS log2_builtin,  -- 3
  LOG(1000)      AS log10;         -- 3 in PostgreSQL

Ten presentes las diferencias:

  • PostgreSQL: LOG(x) es el logaritmo en base 10, mientras que LOG(b, x) toma la base b.
  • MySQL: LOG(x) es el logaritmo natural (como LN), y LOG(b, x) cambia la base; tambien existen LOG2 y LOG10 por separado.
  • ClickHouse: log(x) es el logaritmo natural, con log2 y log10 para lo demas.

Recuerda lo esencial: EXP y LN son inversas, exp(avg(ln)) da una media geometrica, LN(new/old) es una tasa de crecimiento, y la entrada de LN debe ser estrictamente positiva.

Practica con ejercicios reales

Resuelve ejercicios en el entrenador de SQL con corrección instantánea y pistas.

Abrir el entrenador