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.
- 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, nunca89,99. - Com NULL no meio da conta, o resultado é NULL.
Os operadores
| Operador | O que faz | Exemplo | Resultado | Aula |
|---|---|---|---|---|
+ | soma | 7 + 2 | 9 | Funções Numéricas |
- | subtração | 7 - 2 | 5 | |
* | multiplicação | 7 * 2 | 14 | |
/ | divisão. Inteiro dividido por inteiro dá inteiro: a parte decimal é jogada fora. | 7 / 2 | 3 | |
| Se um dos lados for real, a divisão é real | 7 / 2.0 | 3.5 | ||
| Dividir por zero dá NULL, sem erro | 1 / 0 | NULL | ||
% | resto da divisão de inteiros | 7 % 2 | 1 | |
| 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 % 2 | 1.0 | ||
( ) | Mudam a ordem: sem eles, * e / vêm antes de + e -. | 2 + 3 * 4(2 + 3) * 4 | 1420 |
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ção | O que faz | Exemplo | Resultado | Aula |
|---|---|---|---|---|
round(x, casas) | Arredonda para o número de casas pedido (round = "arredondar"). | round(3.14159, 2) | 3.14 | Funçõ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 zero | round(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, -2 | Os 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ção | O que faz | Exemplo | Resultado |
|---|---|---|---|
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, NULL | sign('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 é NULL | max(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ção | O que faz | Exemplo | Resultado |
|---|---|---|---|
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: NULL | sqrt(-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): NULL | ln(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ção | O que faz | Exemplo | Resultado |
|---|---|---|---|
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, atanh | As versões hiperbólicas. |
Aleatórios e conversões
| Função | O que faz | Exemplo | Resultado |
|---|---|---|---|
random() | Um inteiro aleatório enorme (positivo ou negativo). Muda a cada execução. | typeof(random()) | integer |
| Um dado de 6 faces | abs(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 conta | Um texto que parece número entra na conta como número. | '10' + 5 | 15 |
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
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.
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).
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
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.
| Para | SQLite | MySQL | PostgreSQL | SQL Server |
|---|---|---|---|---|
5 / 2 | 2 (inteiro) | 2,5: o / sempre dá decimal; a divisão inteira é 5 DIV 2 | 2 (corta em direção ao zero); também div(5, 2) | 2 (inteiro) |
| dividir por zero | NULL | NULL | erro (division_by_zero) | erro |
log(x) | base 10 | logaritmo natural | base 10 | logaritmo natural |
| log na base b | log(b, x) | LOG(b, x) | log(b, x) | LOG(x, b) (base no fim) |
| cortar casas | trunc(x) | TRUNCATE(x, casas) | trunc(x), trunc(x, casas) | ROUND(x, casas, 1) |
| arredondar para cima | ceil, ceiling | CEIL, CEILING | ceil, ceiling | CEILING |
| aleatório | random(): inteiro enorme | RAND(): real entre 0 e 1 | random(): real entre 0 e 1 | RAND() |
| maior da linha | max(a, b) | GREATEST(a, b) | greatest(a, b) | GREATEST(a, b) (2022+) |
| potência | pow, power | POW, POWER | power, 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); escreva7 / 2.0. Dividir por zero dá NULL. - Arredondar:
round(x, casas); para cimaceil; para baixofloor; cortartruncouCAST(x AS INTEGER). abs,sign, emax/mincom vários valores (nos outros bancos,GREATEST/LEAST).pow,sqrt,exp,ln; no SQLite,log(x)é na base 10.- Ângulos em radianos:
radians()edegrees()convertem. - Decimais são aproximados: arredonde antes de comparar, e guarde dinheiro em centavos quando a exatidão importa.