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,
LOG(1000) AS b,
LOG(2, 8) AS c,
LOG(2, 1024) AS d;
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.
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,
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
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.
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,
LOG(100) AS log10,
LN(8) / LN(2) AS log2_via_ln,
LOG(2, 8) AS log2_builtin;
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.
LOGdevolve 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 eLOG(b, x)em uma base arbitraria.Duas formas de LOG no PostgreSQL
Sem um segundo argumento,
LOGcalcula 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".numeric, entao a precisao e alta, mas e mais lento quedouble precision.LOG(0)eLOG(-5)lancam um erro em vez de retornarNULL.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 (basee), 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(x), MySQLLOG10(x). A funcaoLOG10existe nos dois e e inequivoca.LN(x); significa baseetanto no PostgreSQL quanto no MySQL.LOG(b, x), MySQL tem a mesma sintaxeLOG(b, x)com a mesma ordem de argumentos, entao porta sem problemas.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:
0e 1..9,1e 10..99,2e 100..999. Um truque relacionado e contar os digitos de um inteiro: a contagem de digitos eFLOOR(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;Relacao com LN e mudanca de base
LOGeLNsao parentes: ambos calculam um logaritmo, so muda a base.LN(x)e basee,LOG(x)e base 10 eLOG(b, x)e baseb. 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; -- 3Diferencas por dialeto:
LOG(x)e base 10;LOG(b, x)e arbitraria;LN(x)e natural.LOG(x)e natural (basee); para base 10 useLOG10(x); tambem existeLOG2(x).log(x)eln(x)sao naturais; uselog10(x)para base 10 elog2(x)para base 2. Nao existe a formalog(b, x), entao uselog(x) / log(b).Lembre de tres coisas: no PostgreSQL
LOG(x)e base 10, no MySQL esse mesmoLOG(x)e o logaritmo natural, e para evitar confusao escrevaLOG10eLNde forma explicita.