Целочисленное деление

Целочисленное деление

Иногда недоумение у начинающих работать с SQL Server вызывают результаты подобных запросов:

select 1/3 as a, 5/3 as b;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]

Одни (подозреваю, что это пользователи MySQL или Oracle) ожидают результаты типа

ab
0.33331.6667

т.е. вещественное число, другие -

ab
02

т.е. округления к ближайшему целому. В то время как SQL Server дает

ab
01

Чтобы развеять это недоумение, скажу, что операция “/” просто обозначает целочисленное деление (а именно, дает в результате неполное частное), если операнды являются целыми числами. Т.е. отдельного обозначения для этой операции нет, и используется символ “обычного” деления. Если же вы хотите получить десятичное число, то нужно привести хотя бы один операнд к вещественному типу явно (первый столбец) или неявно (второй столбец):

select cast(1 as DEC(12,4))/3 as a, 5./3 as b;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]
ab
0.3333331.66667

Операция получения остатка от деления в SQL Server обозначается “%”:

select 1 % 3 as a, 5 % 3 as b;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]
ab
12

Теперь что касается некоторых других СУБД.

PostgreSQL ведет себя аналогично SQL Server.

В MySQL для получения неполного частного используется специальный оператор DIV:

select 1 DIV 3 as a, 5 DIV 3 as b;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]

Остаток от деления можно также получить в стиле а-ля Паскаль:

select 1 MOD 3 as a, 5 MOD 3 as b;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]

Хотя будет работать и “общепринятое”

select 1 % 3 as a, 5 % 3 as b;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]

В Oracle вообще нет операции для получения неполного частного, поэтому результат деления

select 1/3 as a, 5/3 as b from dual;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]
ab
0.3333331.66667

потребуется вручную приводить к целому типу с желаемым результатом, например, так:

select CEIL(1/3) as a, CEIL(5/3) as b from dual;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]
ab
12

или так

select FLOOR(1/3) as a, FLOOR(5/3) as b from dual;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]
ab
01

Для получения остатка от деления в Oracle используется функция MOD:

select MOD(1,3) as a, MOD(5,3) as b from dual;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]

Наконец, если делитель равен нулю:

select 1/0 as a;
🚫
[[ error ]]
[[ column ]]
NULL [[ value ]]

то MySQL возвращает NULL, в то время как другие рассматриваемые здесь СУБД дают ошибку деления на ноль.

Рекомендуемые упражнения:137