SQL Funções Numéricas

Esta é a página de consulta rápida das contas no SQLite 3.50: os operadores (+, -, *, /, %), o arredondamento, as potências, os logaritmos, os ângulos e os números aleatórios. Cada linha traz um exemplo e o resultado real. A explicação passo a passo está na aula Funções Numéricas.

Como ler as tabelas
  • Exemplo vai dentro de um SELECT: SELECT round(3.14159, 2);.
  • Resultado foi colhido no editor do guia (SQLite 3.50.4). Repare no .0: 3 é um número inteiro, 3.0 é um número real (com casas decimais). A diferença importa, como você vai ver na divisão.
  • O SQLite usa ponto como separador decimal: 89.99, nunca 89,99.
  • Com NULL no meio da conta, o resultado é NULL.

Os operadores

OperadorO que fazExemploResultadoAula
+soma7 + 29Funções Numéricas
-subtração7 - 25
*multiplicação7 * 214
/divisão. Inteiro dividido por inteiro dá inteiro: a parte decimal é jogada fora.7 / 23
Se um dos lados for real, a divisão é real7 / 2.03.5
Dividir por zero dá NULL, sem erro1 / 0NULL
%resto da divisão de inteiros7 % 21
O resto fica com o sinal do primeiro número-7 % 2-1
Com número real, o % corta as casas antes (use mod)7.5 % 21.0
( )Mudam a ordem: sem eles, * e / vêm antes de + e -.2 + 3 * 4
(2 + 3) * 4
14
20

O % é ótimo para separar pares e ímpares:

SELECT id,
       id % 2 AS resto,
       CASE id % 2 WHEN 0 THEN 'par' ELSE 'ímpar' END AS tipo
FROM pedidos
LIMIT 4;

Arredondar e cortar

FunçãoO que fazExemploResultadoAula
round(x, casas)Arredonda para o número de casas pedido (round = "arredondar").round(3.14159, 2)3.14Funções Numéricas
round(x)Sem as casas: arredonda para inteiro, mas o resultado continua real.round(89.99)90.0
O meio (.5) vai para longe do zeroround(2.5), round(-2.5)3.0, -3.0
Casas negativas contam como 0 (não arredonda para dezenas)round(1234.5678, -2)1235.0
ceil(x), ceiling(x)Arredonda para cima (ceiling = "teto").ceil(2.1), ceil(-2.1)3.0, -2.0
floor(x)Arredonda para baixo (floor = "chão").floor(2.9), floor(-2.1)2.0, -3.0
trunc(x)Corta as casas decimais, indo em direção ao zero (truncate = "truncar").trunc(2.9), trunc(-2.9)2.0, -2.0
CAST(x AS INTEGER)Converte para inteiro, cortando as casas (como o trunc, mas o resultado é inteiro).CAST(2.9 AS INTEGER), CAST(-2.9 AS INTEGER)2, -2Os Tipos no SQLite

Os quatro jeitos lado a lado, nos preços da loja:

SELECT nome, preco,
       round(preco) AS arredondado,
       ceil(preco)  AS para_cima,
       floor(preco) AS para_baixo,
       trunc(preco) AS cortado
FROM produtos
WHERE id IN (1, 2, 3, 20);

Sinal, maior e menor

FunçãoO que fazExemploResultado
abs(x)Valor absoluto: o número sem o sinal (absolute).abs(-3.5)3.5
sign(x)O sinal: -1 (negativo), 0 ou 1 (positivo).sign(-8), sign(0), sign(3.2)-1, 0, 1
Com texto que não é número, NULLsign('abc')NULL
max(a, b, …)Com dois ou mais argumentos: o maior deles.max(3, 9, 4)9
min(a, b, …)O menor deles.min(3, 9, 4)3
Se algum for NULL, o resultado é NULLmax(3, NULL, 4)NULL
max com um argumento é outra coisa

max(preco), com uma coluna só, é a função agregada: o maior preço de todas as linhas. Veja MAX() e Funções Agregadas. Com dois ou mais valores, compara os valores da mesma linha. Nos outros bancos, essa segunda forma se chama GREATEST e LEAST.


Potências, raízes e logaritmos

FunçãoO que fazExemploResultado
pow(x, y), power(x, y)x elevado a y (power = "potência").pow(2, 10)1024.0
power(1.1, 2)1.21
sqrt(x)Raiz quadrada (square root).sqrt(16), sqrt(2)4.0, 1.4142135623731
De número negativo: NULLsqrt(-1)NULL
exp(x)O número e (2,718…) elevado a x.exp(1)2.71828182845905
ln(x)Logaritmo natural (base e).ln(exp(1))1.0
log(x), log10(x)Logaritmo na base 10.log(1000)3.0
log(b, x)Logaritmo de x na base b (a base vem primeiro).log(2, 8)3.0
log2(x)Logaritmo na base 2.log2(1024)10.0
Fora do domínio (zero, negativo): NULLln(0)NULL
mod(x, y)Resto da divisão, também com números reais.mod(7.5, 2)1.5

Ângulos (trigonometria)

As funções de ângulo trabalham em radianos. Para usar graus, converta com radians().

FunçãoO que fazExemploResultado
pi()O número π.pi()3.14159265358979
radians(graus)Graus → radianos.radians(180)3.14159265358979
degrees(rad)Radianos → graus.degrees(pi())180.0
sin(x), cos(x), tan(x)Seno, cosseno, tangente.sin(radians(30)), cos(0), tan(radians(45))0.5, 1.0, 1.0
asin(x), acos(x), atan(x)As inversas (arco seno, arco cosseno, arco tangente).degrees(asin(0.5))30.0
atan2(y, x)Arco tangente de y/x, com o quadrante certo.atan2(1, 1)0.785398163397448
sinh, cosh, tanh, asinh, acosh, atanhAs versões hiperbólicas.

Aleatórios e conversões

FunçãoO que fazExemploResultado
random()Um inteiro aleatório enorme (positivo ou negativo). Muda a cada execução.typeof(random())integer
Um dado de 6 facesabs(random()) % 6 + 1(de 1 a 6, cada vez um)
randomblob(n)n bytes aleatórios (tipo blob).length(randomblob(4))4
CAST(x AS REAL)Converte para real.CAST('12.5' AS REAL)12.5
CAST(x AS INTEGER)Converte para inteiro. De um texto, aproveita os números do começo…CAST('12abc' AS INTEGER)12
…e dá 0 se não houver nenhum.CAST('abc' AS INTEGER)0
texto numa contaUm texto que parece número entra na conta como número.'10' + 515
typeof(x)Diz se o valor é integer ou real.typeof(7 / 2), typeof(7 / 2.0)integer, real

Para sortear linhas, junte random() com ORDER BY: SELECT nome FROM clientes ORDER BY random() LIMIT 1; escolhe um cliente ao acaso a cada Rodar.


As três armadilhas

1. A divisão inteira

A Ana quer a média de 7 itens em 2 caixas e escreve 7 / 2. O SQLite responde 3: inteiro dividido por inteiro dá inteiro. Os jeitos de pedir a divisão "de verdade":

SELECT 7 / 2 AS inteiro,
       7 / 2.0 AS decimal,
       CAST(7 AS REAL) / 2 AS com_cast,
       7 % 2 AS resto;

Isso acontece de verdade com colunas: estoque / 2 (estoque é INTEGER) também corta as casas. Multiplique por 1.0 antes: estoque * 1.0 / 2.

2. Os decimais "quase certos" (ponto flutuante)

Números reais são guardados em binário, e frações como 0,1 não têm representação exata em binário. O SQLite mostra só 15 algarismos, então quase sempre o número parece certo:

SELECT 0.1 + 0.2 AS soma,
       0.1 + 0.2 = 0.3 AS igual,
       0.1 + 0.2 - 0.3 AS diferenca,
       round(0.1 + 0.2, 2) = 0.3 AS igual_arredondado;

A soma aparece como 0.3, mas a comparação com 0.3 dá falso (0): a diferença é um número minúsculo (5.55111512312578e-17, ou seja, 0,0000000000000000555). Pelo mesmo motivo, round(2.675, 2) dá 2.67, e não 2.68: o 2,675 guardado é, na verdade, um pouquinho menos que 2,675.

Regra prática: com dinheiro, arredonde (round(x, 2)) antes de comparar ou de mostrar. Sistemas que não podem errar um centavo guardam o valor em centavos, como inteiro (8999 no lugar de 89.99).

3. O número grande demais

O maior inteiro do SQLite é 9.223.372.036.854.775.807. Uma soma que passa disso vira número real (perdendo precisão), e o abs do menor inteiro dá erro:

SELECT abs(-9223372036854775807 - 1);

Na Loja Aurora isso nunca acontece, mas é bom saber que a mensagem integer overflow ("estouro de inteiro") quer dizer isso.


Nos outros bancos

Os nomes e os comportamentos mudam

Conferido nas documentações oficiais do MySQL 8.4 e do PostgreSQL (e, no SQL Server, na própria documentação do SQLite, que compara o log). Trechos só para comparar; não rodam no editor do guia.

ParaSQLiteMySQLPostgreSQLSQL Server
5 / 22 (inteiro)2,5: o / sempre dá decimal; a divisão inteira é 5 DIV 22 (corta em direção ao zero); também div(5, 2)2 (inteiro)
dividir por zeroNULLNULLerro (division_by_zero)erro
log(x)base 10logaritmo naturalbase 10logaritmo natural
log na base blog(b, x)LOG(b, x)log(b, x)LOG(x, b) (base no fim)
cortar casastrunc(x)TRUNCATE(x, casas)trunc(x), trunc(x, casas)ROUND(x, casas, 1)
arredondar para cimaceil, ceilingCEIL, CEILINGceil, ceilingCEILING
aleatóriorandom(): inteiro enormeRAND(): real entre 0 e 1random(): real entre 0 e 1RAND()
maior da linhamax(a, b)GREATEST(a, b)greatest(a, b)GREATEST(a, b) (2022+)
potênciapow, powerPOW, POWERpower, operador ^POWER

Outra diferença: no MySQL e no PostgreSQL, os números DECIMAL/NUMERIC são exatos (sem o problema do 0,1 + 0,2). O SQLite não tem esse tipo: um DECIMAL no CREATE TABLE vira número real ou inteiro (veja Os Tipos no SQLite).


Experimente

Missão: a loja vai dar 10% de desconto em tudo. Mostre o nome, o preco e o preço com desconto (o preço vezes 0.9), arredondado a 2 casas, numa coluna chamada com_desconto.

SELECT nome, preco
FROM produtos;
SELECT nome, preco, round(preco * 0.9, 2) AS com_desconto
FROM produtos;

Resumo

  • Operadores: +, -, *, /, %. Inteiro / inteiro dá inteiro (7 / 2 = 3); escreva 7 / 2.0. Dividir por zero dá NULL.
  • Arredondar: round(x, casas); para cima ceil; para baixo floor; cortar trunc ou CAST(x AS INTEGER).
  • abs, sign, e max/min com vários valores (nos outros bancos, GREATEST/LEAST).
  • pow, sqrt, exp, ln; no SQLite, log(x) é na base 10.
  • Ângulos em radianos: radians() e degrees() convertem.
  • Decimais são aproximados: arredonde antes de comparar, e guarde dinheiro em centavos quando a exatidão importa.