TRUNC descarta a parte fracionaria de um numero sem arredonda-lo: tudo o que vem depois do ponto e simplesmente cortado. Ao contrario de ROUND, a direcao e sempre a mesma — em direcao a zero — entao o resultado e previsivel tanto para valores positivos quanto negativos.
O que o TRUNC faz
Na sua forma mais simples, TRUNC(x) retorna a parte inteira de um numero, descartando a fracao. Nao ha arredondamento para o mais proximo: 3.99 vira 3, e nao 4.
SELECT
TRUNC(3.99) AS a,
TRUNC(3.01) AS b,
TRUNC(-3.99) AS c,
TRUNC(2.5) AS d;
Propriedades principais:
- O truncamento vai sempre em direcao a zero, e nao para baixo:
-3.99 da -3, porque -3 esta mais perto de zero que -4.
ROUND(2.5) daria 3, mas TRUNC(2.5) da 2: o TRUNC nunca olha para os digitos que descarta.
- O tipo do resultado e
numeric, entao a precisao e preservada.
TRUNC(x, n): cortar por casas decimais
O segundo argumento define quantos digitos depois do ponto manter. O resto e cortado sem arredondar.
SELECT
TRUNC(123.4567, 2) AS two_dp,
TRUNC(123.4567, 0) AS zero_dp,
TRUNC(123.4567, -1) AS neg_one;
Um n negativo trunca a esquerda do ponto: -1 zera as unidades, -2 as dezenas. Aplique isso na tabela employees para agrupar salarios em centenas grosseiras sem arredondar para cima:
SELECT
name,
salary,
TRUNC(salary, -2) AS salary_bucket
FROM employees
ORDER BY salary DESC;
Um funcionario que ganha 4999 cai no grupo 4900, e nao 5000 — o truncamento nunca empurra um valor para a proxima casa.
TRUNC contra FLOOR em numeros negativos
Para numeros positivos, TRUNC e FLOOR parecem identicos. A divergencia comeca nos negativos: FLOOR arredonda para baixo (em direcao a menos infinito), enquanto TRUNC arredonda em direcao a zero.
SELECT
FLOOR(-3.2) AS floor_neg,
TRUNC(-3.2) AS trunc_neg,
FLOOR(3.2) AS floor_pos,
TRUNC(3.2) AS trunc_pos;
Isso e facil de transformar em bug. Digamos que orders guarde reembolsos com amount negativo e voce queira os "dolares inteiros":
SELECT
id,
amount,
FLOOR(amount) AS whole_floor,
TRUNC(amount) AS whole_trunc
FROM orders
WHERE amount < 0;
Pegadinha: se voce quer um "descartar a fracao" simetrico, use TRUNC. O FLOOR sobre reembolsos infla o valor debitado em um dolar inteiro.
Truncar dinheiro contra arredondar
Dinheiro e um campo minado a parte. A contabilidade costuma querer arredondamento (ROUND), mas alguns calculos — taxas, acumulo de juros, dividir um preco — sao obrigados por lei ou contrato a truncar, para nunca "presentear" o cliente com um centavo a mais.
SELECT
u.id,
SUM(o.amount) AS gross,
ROUND(SUM(o.amount) * 0.029, 2) AS fee_rounded,
TRUNC(SUM(o.amount) * 0.029, 2) AS fee_truncated
FROM users u
JOIN orders o ON o.user_id = u.id
WHERE o.status = 'paid'
GROUP BY u.id;
Lembre-se:
ROUND(2.575, 2) pode dar 2.58, enquanto TRUNC(2.575, 2) da sempre 2.57.
- O truncamento subestima o resultado de forma sistematica; o arredondamento nao. Escolha de forma deliberada.
- Calcule sobre
numeric, e nao sobre float: TRUNC de um float binario pode te surpreender por causa do erro de representacao.
MySQL: a funcao se chama TRUNCATE
O MySQL nao tem a funcao TRUNC — seu papel e cumprido por TRUNCATE, e ali o segundo argumento e obrigatorio.
SELECT
TRUNCATE(123.4567, 2) AS two_dp,
TRUNCATE(123.4567, 0) AS zero_dp;
Nao confunda com o comando TRUNCATE TABLE, que esvazia uma tabela instantaneamente — essa e uma operacao completamente diferente. O ClickHouse oferece tanto trunc(x) quanto truncate(x, n) como sinonimos. Lembre-se de uma coisa: TRUNC significa "cortar em direcao a zero sem arredondar", e o nome da funcao e se o segundo argumento e obrigatorio dependem do motor.
TRUNCdescarta a parte fracionaria de um numero sem arredonda-lo: tudo o que vem depois do ponto e simplesmente cortado. Ao contrario deROUND, a direcao e sempre a mesma — em direcao a zero — entao o resultado e previsivel tanto para valores positivos quanto negativos.O que o TRUNC faz
Na sua forma mais simples,
TRUNC(x)retorna a parte inteira de um numero, descartando a fracao. Nao ha arredondamento para o mais proximo:3.99vira3, e nao4.SELECT TRUNC(3.99) AS a, -- 3 TRUNC(3.01) AS b, -- 3 TRUNC(-3.99) AS c, -- -3 TRUNC(2.5) AS d; -- 2Propriedades principais:
-3.99da-3, porque-3esta mais perto de zero que-4.ROUND(2.5)daria3, masTRUNC(2.5)da2: o TRUNC nunca olha para os digitos que descarta.numeric, entao a precisao e preservada.TRUNC(x, n): cortar por casas decimais
O segundo argumento define quantos digitos depois do ponto manter. O resto e cortado sem arredondar.
SELECT TRUNC(123.4567, 2) AS two_dp, -- 123.45 TRUNC(123.4567, 0) AS zero_dp, -- 123 TRUNC(123.4567, -1) AS neg_one; -- 120Um
nnegativo trunca a esquerda do ponto:-1zera as unidades,-2as dezenas. Aplique isso na tabelaemployeespara agrupar salarios em centenas grosseiras sem arredondar para cima:SELECT name, salary, TRUNC(salary, -2) AS salary_bucket FROM employees ORDER BY salary DESC;Um funcionario que ganha
4999cai no grupo4900, e nao5000— o truncamento nunca empurra um valor para a proxima casa.TRUNC contra FLOOR em numeros negativos
Para numeros positivos,
TRUNCeFLOORparecem identicos. A divergencia comeca nos negativos:FLOORarredonda para baixo (em direcao a menos infinito), enquantoTRUNCarredonda em direcao a zero.SELECT FLOOR(-3.2) AS floor_neg, -- -4 TRUNC(-3.2) AS trunc_neg, -- -3 FLOOR(3.2) AS floor_pos, -- 3 TRUNC(3.2) AS trunc_pos; -- 3Isso e facil de transformar em bug. Digamos que
ordersguarde reembolsos comamountnegativo e voce queira os "dolares inteiros":SELECT id, amount, FLOOR(amount) AS whole_floor, -- -16 para -15.30 TRUNC(amount) AS whole_trunc -- -15 para -15.30 FROM orders WHERE amount < 0;Pegadinha: se voce quer um "descartar a fracao" simetrico, use
TRUNC. OFLOORsobre reembolsos infla o valor debitado em um dolar inteiro.Truncar dinheiro contra arredondar
Dinheiro e um campo minado a parte. A contabilidade costuma querer arredondamento (
ROUND), mas alguns calculos — taxas, acumulo de juros, dividir um preco — sao obrigados por lei ou contrato a truncar, para nunca "presentear" o cliente com um centavo a mais.SELECT u.id, SUM(o.amount) AS gross, ROUND(SUM(o.amount) * 0.029, 2) AS fee_rounded, -- arredondamento TRUNC(SUM(o.amount) * 0.029, 2) AS fee_truncated -- truncamento FROM users u JOIN orders o ON o.user_id = u.id WHERE o.status = 'paid' GROUP BY u.id;Lembre-se:
ROUND(2.575, 2)pode dar2.58, enquantoTRUNC(2.575, 2)da sempre2.57.numeric, e nao sobrefloat:TRUNCde umfloatbinario pode te surpreender por causa do erro de representacao.MySQL: a funcao se chama TRUNCATE
O MySQL nao tem a funcao
TRUNC— seu papel e cumprido porTRUNCATE, e ali o segundo argumento e obrigatorio.-- MySQL SELECT TRUNCATE(123.4567, 2) AS two_dp, -- 123.45 TRUNCATE(123.4567, 0) AS zero_dp; -- 123Nao confunda com o comando
TRUNCATE TABLE, que esvazia uma tabela instantaneamente — essa e uma operacao completamente diferente. O ClickHouse oferece tantotrunc(x)quantotruncate(x, n)como sinonimos. Lembre-se de uma coisa: TRUNC significa "cortar em direcao a zero sem arredondar", e o nome da funcao e se o segundo argumento e obrigatorio dependem do motor.