POWER(base, expoente) eleva um numero a uma potencia: POWER(2, 10) e 1024. E a ferramenta de base para calculos de crescimento, normalizacao de metricas e extracao de raizes por meio de um expoente fracionario.
Sintaxe basica
POWER recebe dois argumentos — a base e o expoente — e retorna um numero de ponto flutuante (double precision no PostgreSQL). O alias POW funciona no MySQL e no ClickHouse; o PostgreSQL aceita os dois nomes.
SELECT POWER(2, 10) AS kib,
POWER(10, 6) AS million,
POWER(2, -1) AS half;
Um expoente negativo produz uma fracao, e um expoente zero sempre e um. O PostgreSQL tambem tem um operador infixo ^ que fica bem dentro de formulas:
SELECT 2 ^ 10 AS via_operator;
- No MySQL e no ClickHouse,
^ e um XOR bit a bit, nao uma potencia. La use POW.
- O resultado e sempre real; para uma resposta inteira envolva em
ROUND(...)::bigint.
Expoentes fracionarios e raizes
Uma raiz n-esima e apenas elevar um valor a potencia 1/n. A raiz quadrada tem a sua propria funcao, SQRT, mas POWER te da qualquer raiz.
SELECT POWER(27, 1.0 / 3) AS cube_root,
POWER(16, 0.25) AS fourth_root,
SQRT(2) AS sqrt2;
Use isso para comprimir a dispersao dos valores de pedidos com uma raiz cubica, um truque comum para amortecer outliers em paineis:
SELECT id,
amount,
ROUND(POWER(amount, 1.0 / 3), 2) AS dampened
FROM orders
WHERE status = 'paid'
ORDER BY amount DESC;
A media geometrica dos salarios por departamento e outro caso em que EXP e LN brilham, mas uma raiz tambem pode ser expressa por POWER:
SELECT dept,
ROUND(EXP(AVG(LN(salary))), 2) AS geo_mean_salary
FROM employees
GROUP BY dept;
- Escreva
1.0 / 3, nao 1 / 3: no PostgreSQL e no MySQL a divisao inteira de 1 / 3 e 0, o que colapsa todo o resultado para 1.
Juros compostos e crescimento
A formula classica de capitalizacao e base * (1 + taxa) ^ periodos. Vamos projetar onde fica o valor medio do pedido se ele crescer 3% ao mes durante um ano inteiro.
SELECT ROUND(AVG(amount), 2) AS avg_now,
ROUND(AVG(amount) * POWER(1 + 0.03, 12), 2) AS avg_in_a_year
FROM orders
WHERE status = 'paid';
O problema inverso — encontrar a taxa media de crescimento mensal (CAGR) dos cadastros — tambem se apoia em POWER com um expoente fracionario. A base deve ser a razao entre o ultimo valor e o primeiro (last_count / first_count), e o expoente e um sobre o numero de periodos: POWER(last_count / first_count, 1.0 / periodos) - 1. Um simples COUNT(*) sobre todo o intervalo nao da essa razao: ele conta linhas, nao o crescimento delas do primeiro mes ao ultimo. Por isso pegamos os cadastros do primeiro e do ultimo mes separadamente e dividimos um pelo outro. Repare no 1.0 do expoente e na conversao para numeric, para que nenhuma divisao colapse para zero:
WITH monthly AS (
SELECT date_trunc('month', created_at) AS m,
COUNT(*) AS signups
FROM users
GROUP BY 1
),
bounds AS (
SELECT (SELECT signups FROM monthly ORDER BY m ASC LIMIT 1) AS first_count,
(SELECT signups FROM monthly ORDER BY m DESC LIMIT 1) AS last_count,
(SELECT COUNT(*) - 1 FROM monthly) AS periods
)
SELECT ROUND(
(POWER(last_count::numeric / first_count, 1.0 / periods) - 1) * 100, 2
) AS monthly_growth_pct
FROM bounds;
Overflow e pegadinhas
As potencias crescem de forma explosiva. Um expoente grande estoura o tipo rapidamente, e o PostgreSQL lanca value out of range: overflow em vez de um NULL silencioso.
SELECT POWER(10, 308);
SELECT POWER(10, 309);
- Uma base negativa com expoente fracionario (
POWER(-8, 0.5)) e um numero complexo; o PostgreSQL lanca um erro em vez de retornar NaN.
- No PostgreSQL,
POWER(numeric, numeric) e mais preciso, porem mais caro que a versao de double precision. Converta para numeric de forma deliberada quando lidar com dinheiro.
- O
pow do ClickHouse sempre retorna Float64, entao espere erro de arredondamento em magnitudes grandes.
POWER(0, 0) e 1 nos tres motores — uma convencao matematica, nao um bug.
Mantenha os expoentes dentro de limites razoaveis, converta os tipos de forma explicita e use 1.0 / n para as raizes; assim POWER continua sendo uma ferramenta previsivel tanto para analise quanto para formulas financeiras.
POWER(base, expoente)eleva um numero a uma potencia:POWER(2, 10)e1024. E a ferramenta de base para calculos de crescimento, normalizacao de metricas e extracao de raizes por meio de um expoente fracionario.Sintaxe basica
POWERrecebe dois argumentos — a base e o expoente — e retorna um numero de ponto flutuante (double precisionno PostgreSQL). O aliasPOWfunciona no MySQL e no ClickHouse; o PostgreSQL aceita os dois nomes.SELECT POWER(2, 10) AS kib, -- 1024 POWER(10, 6) AS million, -- 1000000 POWER(2, -1) AS half; -- 0.5Um expoente negativo produz uma fracao, e um expoente zero sempre e um. O PostgreSQL tambem tem um operador infixo
^que fica bem dentro de formulas:SELECT 2 ^ 10 AS via_operator; -- 1024 in PostgreSQL^e um XOR bit a bit, nao uma potencia. La usePOW.ROUND(...)::bigint.Expoentes fracionarios e raizes
Uma raiz n-esima e apenas elevar um valor a potencia
1/n. A raiz quadrada tem a sua propria funcao,SQRT, masPOWERte da qualquer raiz.SELECT POWER(27, 1.0 / 3) AS cube_root, -- 3 POWER(16, 0.25) AS fourth_root, -- 2 SQRT(2) AS sqrt2; -- 1.4142...Use isso para comprimir a dispersao dos valores de pedidos com uma raiz cubica, um truque comum para amortecer outliers em paineis:
SELECT id, amount, ROUND(POWER(amount, 1.0 / 3), 2) AS dampened FROM orders WHERE status = 'paid' ORDER BY amount DESC;A media geometrica dos salarios por departamento e outro caso em que
EXPeLNbrilham, mas uma raiz tambem pode ser expressa porPOWER:SELECT dept, ROUND(EXP(AVG(LN(salary))), 2) AS geo_mean_salary FROM employees GROUP BY dept;1.0 / 3, nao1 / 3: no PostgreSQL e no MySQL a divisao inteira de1 / 3e0, o que colapsa todo o resultado para1.Juros compostos e crescimento
A formula classica de capitalizacao e
base * (1 + taxa) ^ periodos. Vamos projetar onde fica o valor medio do pedido se ele crescer 3% ao mes durante um ano inteiro.SELECT ROUND(AVG(amount), 2) AS avg_now, ROUND(AVG(amount) * POWER(1 + 0.03, 12), 2) AS avg_in_a_year FROM orders WHERE status = 'paid';O problema inverso — encontrar a taxa media de crescimento mensal (CAGR) dos cadastros — tambem se apoia em
POWERcom um expoente fracionario. A base deve ser a razao entre o ultimo valor e o primeiro (last_count / first_count), e o expoente e um sobre o numero de periodos:POWER(last_count / first_count, 1.0 / periodos) - 1. Um simplesCOUNT(*)sobre todo o intervalo nao da essa razao: ele conta linhas, nao o crescimento delas do primeiro mes ao ultimo. Por isso pegamos os cadastros do primeiro e do ultimo mes separadamente e dividimos um pelo outro. Repare no1.0do expoente e na conversao paranumeric, para que nenhuma divisao colapse para zero:WITH monthly AS ( SELECT date_trunc('month', created_at) AS m, COUNT(*) AS signups FROM users GROUP BY 1 ), bounds AS ( SELECT (SELECT signups FROM monthly ORDER BY m ASC LIMIT 1) AS first_count, (SELECT signups FROM monthly ORDER BY m DESC LIMIT 1) AS last_count, (SELECT COUNT(*) - 1 FROM monthly) AS periods ) SELECT ROUND( (POWER(last_count::numeric / first_count, 1.0 / periods) - 1) * 100, 2 ) AS monthly_growth_pct FROM bounds;Overflow e pegadinhas
As potencias crescem de forma explosiva. Um expoente grande estoura o tipo rapidamente, e o PostgreSQL lanca
value out of range: overflowem vez de umNULLsilencioso.SELECT POWER(10, 308); -- ok, near the double precision limit SELECT POWER(10, 309); -- ERROR: value out of range: overflowPOWER(-8, 0.5)) e um numero complexo; o PostgreSQL lanca um erro em vez de retornarNaN.POWER(numeric, numeric)e mais preciso, porem mais caro que a versao dedouble precision. Converta paranumericde forma deliberada quando lidar com dinheiro.powdo ClickHouse sempre retornaFloat64, entao espere erro de arredondamento em magnitudes grandes.POWER(0, 0)e1nos tres motores — uma convencao matematica, nao um bug.Mantenha os expoentes dentro de limites razoaveis, converta os tipos de forma explicita e use
1.0 / npara as raizes; assimPOWERcontinua sendo uma ferramenta previsivel tanto para analise quanto para formulas financeiras.