REGR_SLOPE e REGR_INTERCEPT sao funcoes de agregacao que ajustam uma reta por minimos quadrados dentro da propria consulta. Juntas elas entregam a equacao y = slope * x + intercept, ou seja, uma linha de tendencia e uma formula de previsao pronta, sem precisar exportar os dados para Python ou R.
Sintaxe e ordem dos argumentos
Ambas as funcoes recebem dois argumentos, e e aqui que mora a principal armadilha. A ordem e: primeiro a variavel dependente y (o que voce preve), depois a independente x (a partir da qual voce preve).
SELECT
REGR_SLOPE(amount, extract(epoch from created_at)) AS slope,
REGR_INTERCEPT(amount, extract(epoch from created_at)) AS intercept,
REGR_COUNT(amount, extract(epoch from created_at)) AS n
FROM orders
WHERE status = 'paid';
O que cada parte faz:
REGR_SLOPE(y, x) -- a inclinacao: quanto y muda em media a cada aumento de uma unidade em x.
REGR_INTERCEPT(y, x) -- onde a reta cruza o eixo y (seu valor em x = 0).
REGR_COUNT(y, x) -- o numero de pares onde ambos os valores nao sao NULL. Esse e o seu tamanho de amostra.
Pegadinha: a ordem e (y, x), nao (x, y). Se inverter, voce ajusta a relacao inversa e a previsao desanda. Lembre pelo significado: "o que prevemos" vem primeiro.
Tendencia de receita por dia
Converta o timestamp em um numero (segundos de epoch) e pergunte se o pedido medio cresce com o tempo. Uma inclinacao escalada para dias le-se melhor do que uma por segundo:
SELECT
REGR_SLOPE(amount, extract(epoch from created_at)) * 86400 AS amount_per_day,
REGR_COUNT(amount, extract(epoch from created_at)) AS sample_size
FROM orders
WHERE status = 'paid';
Um amount_per_day positivo significa que os valores dos pedidos tendem a subir dia apos dia; um negativo, que encolhem. Mantenha o REGR_COUNT ao lado: uma inclinacao sobre tres pontos e ruido, nao uma tendencia.
Previsao sem um pacote externo
Como voce ja tem slope e intercept, prever e apenas substituir um x na equacao da reta. Calcule os coeficientes uma vez em um CTE e preveja a receita em uma data futura:
WITH model AS (
SELECT
REGR_SLOPE(amount, extract(epoch from created_at)) AS slope,
REGR_INTERCEPT(amount, extract(epoch from created_at)) AS intercept
FROM orders
WHERE status = 'paid'
)
SELECT
slope * extract(epoch from TIMESTAMP '2026-12-31') + intercept AS forecast_amount
FROM model;
O mesmo truque nao se limita ao tempo. Pegue o salario em funcao do tamanho da equipe de um gerente -- um ajuste linear por departamento:
SELECT
dept,
REGR_SLOPE(salary, reports) AS salary_per_report,
REGR_INTERCEPT(salary, reports) AS base_salary
FROM (
SELECT
e.dept,
e.salary,
count(r.id) AS reports
FROM employees e
LEFT JOIN employees r ON r.manager_id = e.id
GROUP BY e.id, e.dept, e.salary
) s
GROUP BY dept;
Qualidade do ajuste e armadilhas
A inclinacao sozinha nao diz nada sobre o quao bem a reta descreve os dados. Para isso voce tem REGR_R2 (o coeficiente de determinacao, de 0 a 1) e CORR (correlacao):
SELECT
REGR_R2(amount, extract(epoch from created_at)) AS r_squared,
CORR(amount, extract(epoch from created_at)) AS correlation
FROM orders
WHERE status = 'paid';
Coisas a ter em mente:
- Um
R2 proximo de zero significa que a reta e quase inutil; a previsao nao merece confianca.
- Se todos os
x forem identicos (variancia zero), a inclinacao fica indefinida e a funcao retorna NULL em vez de dar erro.
- Linhas onde
y ou x e NULL sao descartadas -- por isso voce sempre confere com o REGR_COUNT.
- A regressao linear so enxerga uma reta. Ela vai achatar a sazonalidade e o crescimento exponencial e vai te enganar.
Diferencas entre os bancos
- MySQL nao tem funcoes
REGR_*. Calcule a inclinacao na mao: slope = (n*SUM(x*y) - SUM(x)*SUM(y)) / (n*SUM(x*x) - SUM(x)*SUM(x)), e intercept = (SUM(y) - slope*SUM(x)) / n.
- ClickHouse oferece
simpleLinearRegression(x, y), e aqui a ordem dos argumentos e invertida -- x vem primeiro. Ela retorna uma tupla (slope, intercept).
- BigQuery nao tem
REGR_SLOPE nem REGR_INTERCEPT embutidas -- a inclinacao e o intercepto sao calculados na mao com SUM, AVG e COVAR_POP/VAR_POP, ou treina-se um modelo com CREATE MODEL ... OPTIONS(model_type='linear_reg') no BigQuery ML. Snowflake, por outro lado, suporta os padroes REGR_SLOPE(y, x) e REGR_INTERCEPT(y, x), assim como o PostgreSQL.
Quando voce quer uma linha de tendencia rapida ou uma previsao barata dentro do banco, REGR_SLOPE e REGR_INTERCEPT poupam toda uma ida e volta a uma ferramenta analitica externa -- so mantenha a ordem dos argumentos clara e confira o tamanho da amostra.
REGR_SLOPEeREGR_INTERCEPTsao funcoes de agregacao que ajustam uma reta por minimos quadrados dentro da propria consulta. Juntas elas entregam a equacaoy = slope * x + intercept, ou seja, uma linha de tendencia e uma formula de previsao pronta, sem precisar exportar os dados para Python ou R.Sintaxe e ordem dos argumentos
Ambas as funcoes recebem dois argumentos, e e aqui que mora a principal armadilha. A ordem e: primeiro a variavel dependente
y(o que voce preve), depois a independentex(a partir da qual voce preve).SELECT REGR_SLOPE(amount, extract(epoch from created_at)) AS slope, REGR_INTERCEPT(amount, extract(epoch from created_at)) AS intercept, REGR_COUNT(amount, extract(epoch from created_at)) AS n FROM orders WHERE status = 'paid';O que cada parte faz:
REGR_SLOPE(y, x)-- a inclinacao: quantoymuda em media a cada aumento de uma unidade emx.REGR_INTERCEPT(y, x)-- onde a reta cruza o eixoy(seu valor emx = 0).REGR_COUNT(y, x)-- o numero de pares onde ambos os valores nao saoNULL. Esse e o seu tamanho de amostra.Tendencia de receita por dia
Converta o timestamp em um numero (segundos de epoch) e pergunte se o pedido medio cresce com o tempo. Uma inclinacao escalada para dias le-se melhor do que uma por segundo:
SELECT REGR_SLOPE(amount, extract(epoch from created_at)) * 86400 AS amount_per_day, REGR_COUNT(amount, extract(epoch from created_at)) AS sample_size FROM orders WHERE status = 'paid';Um
amount_per_daypositivo significa que os valores dos pedidos tendem a subir dia apos dia; um negativo, que encolhem. Mantenha oREGR_COUNTao lado: uma inclinacao sobre tres pontos e ruido, nao uma tendencia.Previsao sem um pacote externo
Como voce ja tem
slopeeintercept, prever e apenas substituir umxna equacao da reta. Calcule os coeficientes uma vez em um CTE e preveja a receita em uma data futura:WITH model AS ( SELECT REGR_SLOPE(amount, extract(epoch from created_at)) AS slope, REGR_INTERCEPT(amount, extract(epoch from created_at)) AS intercept FROM orders WHERE status = 'paid' ) SELECT slope * extract(epoch from TIMESTAMP '2026-12-31') + intercept AS forecast_amount FROM model;O mesmo truque nao se limita ao tempo. Pegue o salario em funcao do tamanho da equipe de um gerente -- um ajuste linear por departamento:
SELECT dept, REGR_SLOPE(salary, reports) AS salary_per_report, REGR_INTERCEPT(salary, reports) AS base_salary FROM ( SELECT e.dept, e.salary, count(r.id) AS reports FROM employees e LEFT JOIN employees r ON r.manager_id = e.id GROUP BY e.id, e.dept, e.salary ) s GROUP BY dept;Qualidade do ajuste e armadilhas
A inclinacao sozinha nao diz nada sobre o quao bem a reta descreve os dados. Para isso voce tem
REGR_R2(o coeficiente de determinacao, de 0 a 1) eCORR(correlacao):SELECT REGR_R2(amount, extract(epoch from created_at)) AS r_squared, CORR(amount, extract(epoch from created_at)) AS correlation FROM orders WHERE status = 'paid';Coisas a ter em mente:
R2proximo de zero significa que a reta e quase inutil; a previsao nao merece confianca.xforem identicos (variancia zero), a inclinacao fica indefinida e a funcao retornaNULLem vez de dar erro.youxeNULLsao descartadas -- por isso voce sempre confere com oREGR_COUNT.Diferencas entre os bancos
REGR_*. Calcule a inclinacao na mao:slope = (n*SUM(x*y) - SUM(x)*SUM(y)) / (n*SUM(x*x) - SUM(x)*SUM(x)), eintercept = (SUM(y) - slope*SUM(x)) / n.simpleLinearRegression(x, y), e aqui a ordem dos argumentos e invertida --xvem primeiro. Ela retorna uma tupla(slope, intercept).REGR_SLOPEnemREGR_INTERCEPTembutidas -- a inclinacao e o intercepto sao calculados na mao comSUM,AVGeCOVAR_POP/VAR_POP, ou treina-se um modelo comCREATE MODEL ... OPTIONS(model_type='linear_reg')no BigQuery ML. Snowflake, por outro lado, suporta os padroesREGR_SLOPE(y, x)eREGR_INTERCEPT(y, x), assim como o PostgreSQL.Quando voce quer uma linha de tendencia rapida ou uma previsao barata dentro do banco,
REGR_SLOPEeREGR_INTERCEPTpoupam toda uma ida e volta a uma ferramenta analitica externa -- so mantenha a ordem dos argumentos clara e confira o tamanho da amostra.