Подтвердить что ты не робот

Почему точность уменьшается при умножении суммы на другое число

Я столкнулся со следующей ошибкой (или функцией) в SQL Server.

Когда я использую SUM (*column*), где column имеет тип numeric(18, 8) и умножает его на любое другое число (целое или десятичное), точность результата уменьшается до numeric(18, 6).

Вот пример script, чтобы продемонстрировать.

CREATE TABLE #temp (Qnty numeric(18,8))

INSERT INTO #temp (Qnty) VALUES (0.00000001)
INSERT INTO #temp (Qnty) VALUES (0.00000002)
INSERT INTO #temp (Qnty) VALUES (0.00000003)

SELECT Qnty, 1*Qnty
FROM #temp

SELECT (-1)*SUM(Qnty), SUM(Qnty), -SUM(Qnty), SUM(Qnty) * CAST(2.234 as numeric(18,8))
FROM #temp

DROP TABLE #temp

Результат второго запроса SELECT

0.000000    0.00000006  -0.00000006 0.000000

Как вы можете видеть, я умножаю SUM, результат - 0.000000

Может ли кто-нибудь объяснить странное поведение?

UPD. Я выполнил этот запрос в SQL Management Studio 2000, 2005 и 2008 SQL Server.

4b9b3361

Ответ 1

Агрегация numeric(18, 8) с SUM приводит к типу данных numeric(38, 8).

Как вычисляется результирующий тип данных при умножении на числовое число: Точность, масштаб и длина (Transact-SQL)

Тип данных для вашей константы -1 - numeric(1, 0)

Точность p1 + p2 + 1= 40
Масштаб s1 + s2= 8

Максимальная точность - 38, и это оставляет вас с numeric(38, 6).

Подробнее о том, почему это numeric(38, 6) здесь: Умножение и разделение с нумерацией

Ответ 2

Если вы читаете справочную страницу SUM, вы увидите, что в десятичном столбце выдается тип NUMERIC(38,6). Вам нужно передать результат SUM в NUMERIC(18,8), чтобы он работал так, как вы хотите.

Выполнение SELECT CAST(SUM(Qnty) as numeric(18,8)) * 2.234 FROM #temp дает 0.00000013404, как вы ожидали.