Целочисленное деление в PostgreSQL: куда пропадает дробная часть?
В PostgreSQL есть одна особенность, на которой легко ошибиться даже при написании простых SQL-запросов: деление целых чисел не всегда возвращает дробный результат.
Разберём целочисленное деление, работу с остатком и особенности дробных чисел.
В моем канале Аналитика FM выпуски про бизнесовые метрики в разных бизнесах, про особенности SQL запросов и работы аналитика.
Канал я веду с нуля подписчиков, рассказываю про аналитику и разбираю различные кейсы на реальных примерах.
Подписывайся, если интересно как устроен мир аналитика!
Целочисленное деление в PostgreSQL: куда пропадает дробная часть?
Представим, что мы делим выручку на количество заказов и хотим получить средний чек.
SELECT 10 / 3;
Какой результат ожидаем?
3.33?
А PostgreSQL вернёт:
3
Почему? Потому что оба числа - целочисленные (integer), а значит, PostgreSQL выполняет целочисленное деление.
При таком делении дробная часть отбрасывается, а не округляется.
1. Целочисленное и обычное деление
Посмотрим на несколько примеров:
SELECT 10 / 3 AS integer_division
, 10.0 / 3 AS decimal_division
, 10::numeric / 3 AS numeric_division;
Результат:
| integer_division | decimal_division | numeric_division |
|:-------------------------:|:---------------------------:|:---------------------------:|
| 3 | 3.333333... | 3.333333... |
В чём разница?
10 / 3 - оба операнда целые числа, поэтому результат целочисленный.
10.0 / 3 - число 10.0 имеет тип numeric, поэтому результат дробный.
10::numeric / 3 - мы явно преобразовали число в numeric.
💡 Важно: если привести результат к numeric уже после деления, дробная часть не вернётся!
SELECT (10 / 3)::numeric;
Результат:
3
Потому что сначала произошло целочисленное деление, и только потом преобразование типа.
Правильно:
SELECT 10::numeric / 3;
2. Отбрасывание дробной части - это не округление
Например:
SELECT 10 / 3 AS result_1,
11 / 3 AS result_2,
8 / 3 AS result_3;
Результат:
result_1 | result_2 | result_3
-------------+--------------+---------
3 | 3 | 2
PostgreSQL просто отбрасывает дробную часть.
Если нам нужно именно округление, используем ROUND():
SELECT ROUND(10::numeric / 3, 2);
Результат:
3.33
3. Деление с остатком
А теперь интереснее.
В PostgreSQL есть оператор %, который возвращает остаток от деления.
Например:
SELECT 10 / 3 AS division,
10 % 3 AS remainder;
Результат:
division | remainder
-------------+----------
3 | 1
Потому что:
10 = 3 * 3 + 1
То есть:
/ - целая часть результата деления для целочисленных операндов;
% - остаток от деления.
Оператор % работает не только с целыми числами, но и с numeric.
Например:
SELECT 10.5 % 3;
Результат:
1.5
4. Где это может пригодиться?
Например, нам нужно определить, является ли число чётным.
Для этого достаточно проверить остаток от деления на 2:
SELECT number,
CASE WHEN number % 2 = 0 THEN 'Чётное'
ELSE 'Нечётное' END AS number_type
FROM numbers;
Или распределить пользователей по группам:
SELECT user_id, user_id % 3 AS group_number
FROM users;
Остаток позволяет распределять записи по группам, проверять кратность чисел и решать другие задачи.
5. Ещё один нюанс: отрицательные числа
Целочисленное деление в PostgreSQL отбрасывает дробную часть в сторону нуля.
SELECT -10 / 3 AS division,
-10 % 3 AS remainder;
Результат:
division | remainder
-------------+----------
-3 | -1
Проверка:
-10 = (-3) * 3 + (-1)
Обратите внимание: остаток в этом случае отрицательный.
🎯 Что важно запомнить
Если оба операнда целочисленные, PostgreSQL выполняет целочисленное деление.
Дробная часть отбрасывается, а не округляется.
Чтобы получить дробный результат, преобразуйте хотя бы один операнд в numeric или тип с плавающей точкой до деления.
ROUND() используется для округления результата.
Оператор % возвращает остаток от деления.
При работе с отрицательными числами целая часть отбрасывается в сторону нуля.
И главное: всегда обращайте внимание на типы данных при делении. Иначе можно получить вполне корректный с точки зрения PostgreSQL, но совершенно неожиданный с точки зрения бизнес-аналитики результат.
Ну а в моем канале Аналитика FM уже есть серия постов про AI-агентов.
Присоединяйся, если интересно разбираться в аналитике данных.







