SQL Server результат приведения арифметики
Я просто смотрю на некоторые очень незначительные несоответствия в отчете, который я составляю, и меня смущает вопрос о том, что является лучшим способом использования SQL-сервера для приведения типов, и если кто-то может мне указать правильное направление, чтобы объяснить, что я ' Я вижу.
Очень небольшая ошибка 1p закрадывается в некоторых случаях с использованием текущего расчета на данных, аналогичных показанным в таблице примера @data
,
Может ли кто-нибудь указать мне правильное направление или хотя бы сказать, на что я смотрю, чтобы я мог продолжить исследования?
Код ниже производит пример вывода:
declare @data table (qty decimal(24,12), price decimal(24,12), multiplier decimal(24,12), rate1 decimal(24,12), rate2 decimal(24,12))
insert into @data
select 21505.000000000000, 30.475000000000, 1.000000000000,1.166500000000, 1.166500000000
select round(data.current_method, 2) as current_method_round, round(data.expected_result_method, 2) as expected_result_round, * from
(select
((qty * price * multiplier) /rate1) * rate2 as current_method,
cast(cast(cast(qty * price * multiplier as decimal(24,12)) / rate1 as decimal(24,12)) * rate2 as decimal(24,12)) as expected_result_method,
((21505.000000000000 * 30.475000000000 * 1.000000000000) / 1.166500000000) * 1.166500000000 as checkvalue,
*
from @data ) data
2 ответа
Вам, вероятно, стоит взглянуть на эту статью, чтобы понять, как влияет точность и масштабирование на выражения, поскольку умножение десятичных дробей требует повышения точности.
Тот факт, что вы получаете два разных результата от этого:
,((qty * price * multiplier) / rate1) * rate2 as current_method
,((qty * price * multiplier) * rate2) / rate1 as current_method2
Подразумевает, что промежуточное выражение в вашем current_method имеет проблему точности.
Эд... не делай этого в SQL! Подобные вещи выглядят ужасно и должны быть в промежуточном программном обеспечении, где лучше понять последствия результатов приведения.
[РЕДАКТИРОВАТЬ] Я подозреваю, что-то где-то преобразуется в где-то с плавающей точкой, вероятно, относится к оператору деления. 1p не может быть точно представлен как число с плавающей запятой.