Точность расчета 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       |
+-----------+-----------+---------------+----------+-----------+----------+----------+------------+
Другие вопросы по тегам