Cet article est actuellement en russe — la traduction en anglais est en cours.
TRUNC отбрасывает дробную часть числа, не округляя его: всё, что после точки, просто срезается. В отличие от ROUND, направление здесь всегда одно — к нулю, поэтому результат предсказуем и для положительных, и для отрицательных значений.
Практическая ценность в том, что вы явно запрещаете числу «перепрыгнуть» на следующий разряд. Это важно в расчётах комиссий, лимитов и технических бакетов, где округление вверх даже на копейку меняет смысл операции.
Что делает TRUNC
В простейшей форме TRUNC(x) возвращает целую часть числа, отбрасывая дробную. Никакого округления к ближайшему: 3.99 превращается в 3, а не в 4.
SELECT
TRUNC(3.99) AS a,
TRUNC(3.01) AS b,
TRUNC(-3.99) AS c,
TRUNC(2.5) AS d;
Ключевые свойства:
- Усечение всегда идёт к нулю, а не вниз:
-3.99 даёт -3, потому что -3 ближе к нулю, чем -4.
ROUND(2.5) дало бы 3, а TRUNC(2.5) — 2: TRUNC вообще не смотрит на отброшенные цифры.
- Тип результата —
numeric, так что точность сохраняется.
TRUNC(x, n): усечение до знаков
Второй аргумент задаёт число знаков после запятой, которые нужно оставить. Остальное срезается без округления.
SELECT
TRUNC(123.4567, 2) AS two_dp,
TRUNC(123.4567, 0) AS zero_dp,
TRUNC(123.4567, -1) AS neg_one;
Отрицательное n усекает слева от запятой: -1 обнуляет единицы, -2 — десятки. Применим это к таблице employees, чтобы показать зарплату «грубыми» сотнями без округления вверх:
SELECT
name,
salary,
TRUNC(salary, -2) AS salary_bucket
FROM employees
ORDER BY salary DESC;
Сотрудник с зарплатой 4999 попадёт в корзину 4900, а не 5000 — усечение никогда не «дотягивает» значение до следующего разряда.
TRUNC против FLOOR на отрицательных числах
Для положительных чисел TRUNC и FLOOR выглядят одинаково. Расхождение начинается на отрицательных: FLOOR округляет вниз (к минус бесконечности), а TRUNC — к нулю.
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;
Это легко превратить в баг. Допустим, в orders хранятся возвраты с отрицательным amount, и вы считаете «целое число долларов»:
SELECT
id,
amount,
FLOOR(amount) AS whole_floor,
TRUNC(amount) AS whole_trunc
FROM orders
WHERE amount < 0;
Грабли: если нужна именно симметрия «отбросить дробь», берите TRUNC. FLOOR на возвратах завысит сумму списания на целый доллар.
Усечение денег vs округление
Деньги — отдельная больная тема. Бухгалтерия обычно требует округления (ROUND), но в некоторых расчётах — комиссии, начисление процентов, дробление цены — закон или договор предписывает именно усечение, чтобы не «дарить» клиенту лишний цент.
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;
Помните:
ROUND(2.575, 2) может дать 2.58, а TRUNC(2.575, 2) — всегда 2.57, потому что отброшенная цифра вообще не учитывается.
- Усечение систематически занижает результат, а округление — нет; на больших объёмах это копится в заметную разницу, поэтому выбирайте осознанно и фиксируйте правило в спецификации расчёта.
- Считайте на
numeric, а не на float: TRUNC от двоичного float может удивить из-за погрешности представления, когда значение вроде 0.29 хранится как чуть меньшее число.
MySQL: функция называется TRUNCATE
В MySQL нет функции TRUNC — её роль играет TRUNCATE, и второй аргумент там обязателен.
SELECT
TRUNCATE(123.4567, 2) AS two_dp,
TRUNCATE(123.4567, 0) AS zero_dp;
Не путайте с командой TRUNCATE TABLE, которая мгновенно очищает таблицу целиком и не имеет ничего общего с округлением чисел — это совсем другая операция, относящаяся к DDL. В ClickHouse есть и trunc(x), и truncate(x, n) как синонимы, причём второй аргумент необязателен, как в PostgreSQL. Запомните одно: TRUNC — это «срезать к нулю без округления», а конкретное имя функции и обязательность второго аргумента зависят от вашей СУБД, так что при переносе запроса между движками этот фрагмент стоит перепроверять первым.
Короткий вывод: используйте TRUNC, когда правило расчёта требует именно усечения, а не «разумного» округления. Если бизнес-логика не фиксирует этот выбор явно, лучше зафиксировать его в требованиях до того, как цифры попадут в отчёт.
TRUNCотбрасывает дробную часть числа, не округляя его: всё, что после точки, просто срезается. В отличие отROUND, направление здесь всегда одно — к нулю, поэтому результат предсказуем и для положительных, и для отрицательных значений.Практическая ценность в том, что вы явно запрещаете числу «перепрыгнуть» на следующий разряд. Это важно в расчётах комиссий, лимитов и технических бакетов, где округление вверх даже на копейку меняет смысл операции.
Что делает TRUNC
В простейшей форме
TRUNC(x)возвращает целую часть числа, отбрасывая дробную. Никакого округления к ближайшему:3.99превращается в3, а не в4.SELECT TRUNC(3.99) AS a, -- 3 TRUNC(3.01) AS b, -- 3 TRUNC(-3.99) AS c, -- -3 TRUNC(2.5) AS d; -- 2Ключевые свойства:
-3.99даёт-3, потому что-3ближе к нулю, чем-4.ROUND(2.5)дало бы3, аTRUNC(2.5)—2: TRUNC вообще не смотрит на отброшенные цифры.numeric, так что точность сохраняется.TRUNC(x, n): усечение до знаков
Второй аргумент задаёт число знаков после запятой, которые нужно оставить. Остальное срезается без округления.
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; -- 120Отрицательное
nусекает слева от запятой:-1обнуляет единицы,-2— десятки. Применим это к таблицеemployees, чтобы показать зарплату «грубыми» сотнями без округления вверх:SELECT name, salary, TRUNC(salary, -2) AS salary_bucket FROM employees ORDER BY salary DESC;Сотрудник с зарплатой
4999попадёт в корзину4900, а не5000— усечение никогда не «дотягивает» значение до следующего разряда.TRUNC против FLOOR на отрицательных числах
Для положительных чисел
TRUNCиFLOORвыглядят одинаково. Расхождение начинается на отрицательных:FLOORокругляет вниз (к минус бесконечности), аTRUNC— к нулю.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; -- 3Это легко превратить в баг. Допустим, в
ordersхранятся возвраты с отрицательнымamount, и вы считаете «целое число долларов»:SELECT id, amount, FLOOR(amount) AS whole_floor, -- -16 for -15.30 TRUNC(amount) AS whole_trunc -- -15 for -15.30 FROM orders WHERE amount < 0;Грабли: если нужна именно симметрия «отбросить дробь», берите
TRUNC.FLOORна возвратах завысит сумму списания на целый доллар.Усечение денег vs округление
Деньги — отдельная больная тема. Бухгалтерия обычно требует округления (
ROUND), но в некоторых расчётах — комиссии, начисление процентов, дробление цены — закон или договор предписывает именно усечение, чтобы не «дарить» клиенту лишний цент.SELECT u.id, SUM(o.amount) AS gross, ROUND(SUM(o.amount) * 0.029, 2) AS fee_rounded, -- rounding TRUNC(SUM(o.amount) * 0.029, 2) AS fee_truncated -- truncation FROM users u JOIN orders o ON o.user_id = u.id WHERE o.status = 'paid' GROUP BY u.id;Помните:
ROUND(2.575, 2)может дать2.58, аTRUNC(2.575, 2)— всегда2.57, потому что отброшенная цифра вообще не учитывается.numeric, а не наfloat:TRUNCот двоичногоfloatможет удивить из-за погрешности представления, когда значение вроде0.29хранится как чуть меньшее число.MySQL: функция называется TRUNCATE
В MySQL нет функции
TRUNC— её роль играетTRUNCATE, и второй аргумент там обязателен.-- MySQL SELECT TRUNCATE(123.4567, 2) AS two_dp, -- 123.45 TRUNCATE(123.4567, 0) AS zero_dp; -- 123Не путайте с командой
TRUNCATE TABLE, которая мгновенно очищает таблицу целиком и не имеет ничего общего с округлением чисел — это совсем другая операция, относящаяся к DDL. В ClickHouse есть иtrunc(x), иtruncate(x, n)как синонимы, причём второй аргумент необязателен, как в PostgreSQL. Запомните одно: TRUNC — это «срезать к нулю без округления», а конкретное имя функции и обязательность второго аргумента зависят от вашей СУБД, так что при переносе запроса между движками этот фрагмент стоит перепроверять первым.Короткий вывод: используйте TRUNC, когда правило расчёта требует именно усечения, а не «разумного» округления. Если бизнес-логика не фиксирует этот выбор явно, лучше зафиксировать его в требованиях до того, как цифры попадут в отчёт.