LOG devuelve el logaritmo de un numero: la potencia a la que hay que elevar la base para obtener el argumento. En PostgreSQL la funcion tiene dos formas: LOG(x) en base 10 y LOG(b, x) en una base arbitraria.
Dos formas de LOG en PostgreSQL
Sin un segundo argumento, LOG calcula el logaritmo en base 10. Si pasas dos argumentos, el primero se convierte en la base.
SELECT
LOG(100) AS a,
LOG(1000) AS b,
LOG(2, 8) AS c,
LOG(2, 1024) AS d;
Propiedades clave:
LOG(x) es el logaritmo en base 10, no el natural.
LOG(b, x) se lee como "logaritmo de x en base b".
- El tipo del resultado es
numeric, asi que la precision es alta pero es mas lento que double precision.
- El argumento debe ser estrictamente positivo:
LOG(0) y LOG(-5) lanzan un error en lugar de devolver NULL.
La trampa principal: LOG en MySQL es el logaritmo natural
Este es el punto mas peligroso al portar consultas. En MySQL LOG(x) con un solo argumento es el logaritmo natural (base e), no el de base 10. La misma llamada devuelve numeros distintos en motores distintos.
SELECT LOG(100) AS surprise;
Para que el codigo no dependa del dialecto, se explicito:
- Logaritmo base 10: PostgreSQL
LOG(x), MySQL LOG10(x). La funcion LOG10 existe en ambos y es inequivoca.
- Logaritmo natural: usa
LN(x); significa base e tanto en PostgreSQL como en MySQL.
- Base arbitraria: PostgreSQL
LOG(b, x), MySQL tiene la misma sintaxis LOG(b, x) con el mismo orden de argumentos, asi que se porta sin problemas.
Cuidado: nunca confies en LOG(x) de un solo argumento en codigo multimotor. Escribe LOG10(x) para base 10 y LN(x) para base e, y el significado sera el mismo en todas partes.
Escalas logaritmicas y conteo de digitos
Los logaritmos comprimen valores que crecen por ordenes de magnitud: importes de pedidos, conteos de eventos, tamanos de archivos. En una escala log "10 y 100" estan tan separados como "100 y 1000".
SELECT
FLOOR(LOG(amount))::int AS magnitude,
COUNT(*) AS orders
FROM orders
WHERE status = 'paid' AND amount > 0
GROUP BY FLOOR(LOG(amount))::int
ORDER BY magnitude;
Aqui los pedidos se agrupan por orden de magnitud: 0 es 1..9, 1 es 10..99, 2 es 100..999. Un truco relacionado es contar los digitos de un entero: el numero de digitos es FLOOR(LOG10(n)) + 1.
SELECT
id,
salary,
FLOOR(LOG(salary))::int + 1 AS digits
FROM employees
WHERE salary > 0
ORDER BY salary DESC;
Cuidado: filtra siempre los valores no positivos con WHERE amount > 0 o NULLIF. Un solo amount = 0 o un reembolso negativo hara que toda la consulta falle con un error de dominio. Una proteccion: LOG(NULLIF(amount, 0)) convierte el cero en NULL en vez de provocar un error.
Relacion con LN y cambio de base
LOG y LN son parientes: ambos calculan un logaritmo, solo cambia la base. LN(x) es base e, LOG(x) es base 10 y LOG(b, x) es base b. Cualquier base se expresa con ellas mediante la formula de cambio de base.
SELECT
LN(100) AS natural_log,
LOG(100) AS log10,
LN(8) / LN(2) AS log2_via_ln,
LOG(2, 8) AS log2_builtin;
Diferencias por dialecto:
- PostgreSQL:
LOG(x) es base 10; LOG(b, x) es arbitraria; LN(x) es natural.
- MySQL:
LOG(x) es natural (base e); para base 10 usa LOG10(x); tambien existe LOG2(x).
- ClickHouse:
log(x) y ln(x) son naturales; usa log10(x) para base 10 y log2(x) para base 2. No hay forma log(b, x), asi que usa log(x) / log(b).
Recuerda tres cosas: en PostgreSQL LOG(x) es base 10, en MySQL ese mismo LOG(x) es el logaritmo natural, y para evitar confusiones escribe LOG10 y LN de forma explicita.
LOGdevuelve el logaritmo de un numero: la potencia a la que hay que elevar la base para obtener el argumento. En PostgreSQL la funcion tiene dos formas:LOG(x)en base 10 yLOG(b, x)en una base arbitraria.Dos formas de LOG en PostgreSQL
Sin un segundo argumento,
LOGcalcula el logaritmo en base 10. Si pasas dos argumentos, el primero se convierte en la base.SELECT LOG(100) AS a, -- 2 (10^2 = 100) LOG(1000) AS b, -- 3 (10^3 = 1000) LOG(2, 8) AS c, -- 3 (2^3 = 8) LOG(2, 1024) AS d; -- 10 (2^10 = 1024)Propiedades clave:
LOG(x)es el logaritmo en base 10, no el natural.LOG(b, x)se lee como "logaritmo de x en base b".numeric, asi que la precision es alta pero es mas lento quedouble precision.LOG(0)yLOG(-5)lanzan un error en lugar de devolverNULL.La trampa principal: LOG en MySQL es el logaritmo natural
Este es el punto mas peligroso al portar consultas. En MySQL
LOG(x)con un solo argumento es el logaritmo natural (basee), no el de base 10. La misma llamada devuelve numeros distintos en motores distintos.-- PostgreSQL: LOG(100) = 2 (base 10) -- MySQL: LOG(100) = 4.605 (base e, natural log) SELECT LOG(100) AS surprise;Para que el codigo no dependa del dialecto, se explicito:
LOG(x), MySQLLOG10(x). La funcionLOG10existe en ambos y es inequivoca.LN(x); significa baseetanto en PostgreSQL como en MySQL.LOG(b, x), MySQL tiene la misma sintaxisLOG(b, x)con el mismo orden de argumentos, asi que se porta sin problemas.Escalas logaritmicas y conteo de digitos
Los logaritmos comprimen valores que crecen por ordenes de magnitud: importes de pedidos, conteos de eventos, tamanos de archivos. En una escala log "10 y 100" estan tan separados como "100 y 1000".
SELECT FLOOR(LOG(amount))::int AS magnitude, -- 0, 1, 2, 3 ... COUNT(*) AS orders FROM orders WHERE status = 'paid' AND amount > 0 GROUP BY FLOOR(LOG(amount))::int ORDER BY magnitude;Aqui los pedidos se agrupan por orden de magnitud:
0es 1..9,1es 10..99,2es 100..999. Un truco relacionado es contar los digitos de un entero: el numero de digitos esFLOOR(LOG10(n)) + 1.SELECT id, salary, FLOOR(LOG(salary))::int + 1 AS digits -- digits in the salary FROM employees WHERE salary > 0 ORDER BY salary DESC;Relacion con LN y cambio de base
LOGyLNson parientes: ambos calculan un logaritmo, solo cambia la base.LN(x)es basee,LOG(x)es base 10 yLOG(b, x)es baseb. Cualquier base se expresa con ellas mediante la formula de cambio de base.SELECT LN(100) AS natural_log, -- 4.605 LOG(100) AS log10, -- 2 LN(8) / LN(2) AS log2_via_ln, -- 3 LOG(2, 8) AS log2_builtin; -- 3Diferencias por dialecto:
LOG(x)es base 10;LOG(b, x)es arbitraria;LN(x)es natural.LOG(x)es natural (basee); para base 10 usaLOG10(x); tambien existeLOG2(x).log(x)yln(x)son naturales; usalog10(x)para base 10 ylog2(x)para base 2. No hay formalog(b, x), asi que usalog(x) / log(b).Recuerda tres cosas: en PostgreSQL
LOG(x)es base 10, en MySQL ese mismoLOG(x)es el logaritmo natural, y para evitar confusiones escribeLOG10yLNde forma explicita.