Точность расчета SQL
Может ли кто-нибудь объяснить поведение этого запроса:
SELECT
0.1 + 0.01,
'',
(CAST(0.1 AS numeric(18,1)))+(CAST(0.01 AS numeric (18,2))),
0.1 + (CAST(0.01 AS numeric (18,2))),
(CAST(0.1 AS numeric(18,1)))+ 0.01,
'',
(CAST(0.1 AS numeric(38,1)))+(CAST(0.01 AS numeric (38,2))),
0.1 + (CAST(0.01 AS numeric (38,2))),
(CAST(0.1 AS numeric(38,1)))+ 0.01
Я не понимаю, почему 38 ведет себя иначе, чем 18?
Я ожидал, что SQL-сервер всегда будет автоматически возвращать результат вычисления с точностью, необходимой для точного отображения результата? Что бы это изменить, вам бы пришлось явным образом привести результат?
1 ответ
Он следует правилам, указанным здесь: точность, масштаб и длина (Transact-SQL) - msdn
Когда вы используете максимальную точность, вы не сможете отрегулировать масштаб, не рискуя потерять точность.
Диаграмма для преобразования типов данных (компонент Database Engine) - msdn
Если вы ввели float
в ваши расчеты, вы получите float
вернуть.
По умолчанию значения с десятичной дробью неявно преобразуются в десятичные / числовые типы данных. Эти неявные преобразования помечены как 'und'
в примере, модифицированном по вашему вопросу:
select
undefined=0.1 + 0.01
,[18,1+18,2] = (cast(0.1 as numeric(18,1)))+(cast(0.01 as numeric (18,2)))
,[und+18,2+18,1] = 0.1 + (cast(0.01 as numeric (18,2)))
,[18,2+und]=(cast(0.1 as numeric(18,1)))+ 0.01
,[38,1+38,2]=(cast(0.1 as numeric(38,1)))+(cast(0.01 as numeric (38,2)))
,[und+38,2] = 0.1 + (cast(0.01 as numeric (38,2)))
,[38,1+und]=(cast(0.1 as numeric(38,1)))+ 0.01
,[38,1+float]=(cast(0.1 as numeric(38,1)))+ convert(float,0.01)
демонстрационный ролик: http://rextester.com/ULVRGS77309
возвращает:
+-----------+-----------+---------------+----------+-----------+----------+----------+------------+
| undefined | 18,1+18,2 | und+18,2+18,1 | 18,2+und | 38,1+38,2 | und+38,2 | 38,1+und | 38,1+float |
+-----------+-----------+---------------+----------+-----------+----------+----------+------------+
| 0,11 | 0,11 | 0,11 | 0,11 | 0,1 | 0,11 | 0,1 | 0,11 |
+-----------+-----------+---------------+----------+-----------+----------+----------+------------+