Float(n)

Как-то в одной социальной сети спросили, как убрать концевые нули в десятичных числах. Это было связано с подготовкой некоего отчета, где денежные суммы конкатенировались с текстом. В постановке задачи указывалось ограничение на два десятичных знака. Вот пример данных и требуемый результат:

данополучить
00
1010
2.52.5
100100
11.3311.33

Предлагались решения, построенные на разборе строки. Я тоже впал в подобную ересь :-) и предложил следующее решение.

SELECT num,
CASE WHEN CAST(num AS INT) = num
           THEN CAST(CAST(num AS INT) AS VARCHAR)
           WHEN CAST(num*10 AS INT) = num*10
           THEN LEFT(CAST(num AS VARCHAR), LEN(CAST(num AS VARCHAR)) - 1)
            WHEN CAST(num*100 AS INT)=num*100
            THEN CAST(num AS VARCHAR)
END fnum
FROM(
SELECT 0.00 as num
UNION ALL SELECT 10.00
UNION ALL SELECT 2.50
UNION ALL SELECT 100
UNION ALL SELECT 11.33
) X;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Не знаю, сколько бы это еще продолжалось, если бы один участник дискуссии не заметил, что все проблемы решает приведение к типу данных FLOAT. Действительно,

SELECT num, CAST(num AS FLOAT) fnum
FROM(
SELECT 0.00 as num
UNION ALL SELECT 10.00
UNION ALL SELECT 2.50
UNION ALL SELECT 100
UNION ALL SELECT 11.33
) X;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Однако при этом нужно помнить о приближенном характере данного типа, а именно о величине мантиссы в научном представлении числа.

В соответствии со стандартом, этот тип данных имеет аргумент - FLOAT(n), который может принимать значения от 1 до 53. SQL Server значения аргумента в диапазоне 1 - 24 трактует как 24, что соответствует точности 7 цифр, а в диапазоне 25 - 53 как 53, что соответствует точности 15 цифр. По умолчанию принимается значение 53.

Продемонстрируем сказанное следующим примером.

SELECT num,
CAST(num AS FLOAT(24)) num_24,
CAST(num AS FLOAT(53)) num_53
FROM(
SELECT 1234567.80 AS num
UNION ALL SELECT  12345678.90
UNION ALL SELECT 123456789012345.60
UNION ALL SELECT 1234567890123456.70
) x;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]
numnum_24num_53
1.23457e+061.23457e+061.23457e+06
1.23457e+071.23457e+071.23457e+07
1.23457e+141.23457e+141.23457e+14
1.23457e+151.23457e+151.23457e+15

MySQL (версия 5.0)

Не поддерживается преобразование к типу FLOAT.

PostgreSQL (версия 8.3.6)

Практически аналогичное поведение, за исключением того, что для параметра в диапазоне 1 – 24 точность составляет 6 цифр. Соответственно последние результаты будут выглядеть так:

numnum_24num_53
1.23457e+061.23457e+061.23457e+06
1.23457e+071.23457e+071.23457e+07
1.23457e+141.23457e+141.23457e+14
1.23457e+151.23457e+151.23457e+15