sqlpostgresqllogmath

LOG no SQL: logaritmo na base 10 e base arbitraria, e a armadilha do MySQL

Como LOG(x) na base 10 e LOG(b, x) em base arbitraria funcionam no PostgreSQL, por que LOG no MySQL e uma armadilha e onde logaritmos ajudam.

3 min de leituraReferencesql · postgresql · log · math · mysql · clickhouse

LOG devolve o logaritmo de um numero: a potencia a que a base precisa ser elevada para produzir o argumento. No PostgreSQL a funcao tem duas formas: LOG(x) na base 10 e LOG(b, x) em uma base arbitraria.

Duas formas de LOG no PostgreSQL

Sem um segundo argumento, LOG calcula o logaritmo na base 10. Passe dois argumentos e o primeiro vira a 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)

Propriedades principais:

  • LOG(x) e o logaritmo na base 10, nao o natural.
  • LOG(b, x) se le como "log de x na base b".
  • O tipo do resultado e numeric, entao a precisao e alta, mas e mais lento que double precision.
  • O argumento precisa ser estritamente positivo: LOG(0) e LOG(-5) lancam um erro em vez de retornar NULL.

A armadilha principal: LOG no MySQL e o logaritmo natural

Este e o ponto mais perigoso ao portar consultas. No MySQL LOG(x) com um unico argumento e o logaritmo natural (base e), nao o de base 10. A mesma chamada retorna numeros diferentes em bancos diferentes.

-- PostgreSQL: LOG(100) = 2     (base 10)
-- MySQL:      LOG(100) = 4.605  (base e, natural log)
SELECT LOG(100) AS surprise;

Para que o codigo nao dependa do dialeto, seja explicito:

  • Log base 10: PostgreSQL LOG(x), MySQL LOG10(x). A funcao LOG10 existe nos dois e e inequivoca.
  • Log natural: use LN(x); significa base e tanto no PostgreSQL quanto no MySQL.
  • Base arbitraria: PostgreSQL LOG(b, x), MySQL tem a mesma sintaxe LOG(b, x) com a mesma ordem de argumentos, entao porta sem problemas.

Atencao: nunca confie em LOG(x) de um unico argumento em codigo multibanco. Escreva LOG10(x) para base 10 e LN(x) para base e, e o significado sera o mesmo em todo lugar.

Escalas logaritmicas e contagem de digitos

Logaritmos comprimem valores que crescem por ordens de grandeza: valores de pedidos, contagens de eventos, tamanhos de arquivo. Em uma escala log "10 e 100" ficam tao distantes quanto "100 e 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 os pedidos sao agrupados por ordem de grandeza: 0 e 1..9, 1 e 10..99, 2 e 100..999. Um truque relacionado e contar os digitos de um inteiro: a contagem de digitos e FLOOR(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;

Atencao: sempre filtre os valores nao positivos com WHERE amount > 0 ou NULLIF. Um unico amount = 0 ou um estorno negativo derruba a consulta inteira com um erro de dominio. Uma protecao: LOG(NULLIF(amount, 0)) transforma o zero em NULL em vez de gerar um erro.

Relacao com LN e mudanca de base

LOG e LN sao parentes: ambos calculam um logaritmo, so muda a base. LN(x) e base e, LOG(x) e base 10 e LOG(b, x) e base b. Qualquer base pode ser expressa por meio deles com a formula de mudanca 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;  -- 3

Diferencas por dialeto:

  • PostgreSQL: LOG(x) e base 10; LOG(b, x) e arbitraria; LN(x) e natural.
  • MySQL: LOG(x) e natural (base e); para base 10 use LOG10(x); tambem existe LOG2(x).
  • ClickHouse: log(x) e ln(x) sao naturais; use log10(x) para base 10 e log2(x) para base 2. Nao existe a forma log(b, x), entao use log(x) / log(b).

Lembre de tres coisas: no PostgreSQL LOG(x) e base 10, no MySQL esse mesmo LOG(x) e o logaritmo natural, e para evitar confusao escreva LOG10 e LN de forma explicita.

Pratique com exercícios reais

Resolva exercícios no treinador de SQL com correção instantânea e dicas.

Abrir o treinador