Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Почему в умноженная сумма на -1 округленяется до 6 знаков?  [new]
rpuLLIa
Member

Откуда:
Сообщений: 23
CREATE TABLE #temp (qnt numeric(18,8)) 

INSERT INTO #temp (qnt) VALUES (0.12345678) 
INSERT INTO #temp (qnt) VALUES (1.23456789) 
INSERT INTO #temp (qnt) VALUES (2.34567890) 

SELECT * 
FROM #temp 


-- Почему жздесь  происходит округление до 6 знаков?
SELECT (-1)*SUM(qnt) 
FROM #temp 
11 янв 13, 15:26    [13754715]     Ответить | Цитировать Сообщить модератору
 Re: Почему в умноженная сумма на -1 округленяется до 6 знаков?  [new]
rpuLLIa
Member

Откуда:
Сообщений: 23
rpuLLIa,

результаты забыл написать:
0.12345678
1.23456789
2.34567890

-3.703704
11 янв 13, 15:28    [13754732]     Ответить | Цитировать Сообщить модератору
 Re: Почему в умноженная сумма на -1 округленяется до 6 знаков?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37053
SELECT (-1.)*SUM(qnt) 
FROM #temp 
11 янв 13, 15:30    [13754751]     Ответить | Цитировать Сообщить модератору
 Re: Почему в умноженная сумма на -1 округленяется до 6 знаков?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37053
Вернее, не так. Нужно у обоих частей выражения задирать scale явным конвертом. Ибо http://msdn.microsoft.com/en-us/library/ms190476.aspx

Сообщение было отредактировано: 11 янв 13, 15:41
11 янв 13, 15:40    [13754864]     Ответить | Цитировать Сообщить модератору
 Re: Почему в умноженная сумма на -1 округленяется до 6 знаков?  [new]
rpuLLIa
Member

Откуда:
Сообщений: 23
Гавриленко Сергей Алексеевич,

Как исправить это понятно, главный вопрос - почему. Я всегда думал что при умножении двух чисел с разным масштабом подсчёт будетвестись со стороны того у кого этот масштаб больше. Ну или же как написано в вашей ссылке:

Операнды выражений обозначены как выражение e1 с точностью p1 и масштабом s2 и выражение e2 с точностью p2 и масштабом s2. Точность и масштаб для любого выражения, отличного от decimal, соответствуют типу данных этого выражения.
e1 * e2 p1 + p2 + 1 s1 + s2
14 янв 13, 06:46    [13764273]     Ответить | Цитировать Сообщить модератору
 Re: Почему в умноженная сумма на -1 округленяется до 6 знаков?  [new]
rpuLLIa
Member

Откуда:
Сообщений: 23
Вроде бы часть логики приходит:
http://msdn.microsoft.com/ru-ru/library/ms190309.aspx

Если оператор связывает два выражения различных типов данных, то по правилам приоритета типов данных определяется, какой тип данных имеет меньший приоритет и будет преобразован в тип данных с большим приоритетом.

16 - int
12 - decimal.

Но!
declare @n numeric(18,8) = 10.234453457357
select (-1) * @n


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

INSERT INTO #temp (qnt) VALUES (0.12345678)
INSERT INTO #temp (qnt) VALUES (1.23456789)
INSERT INTO #temp (qnt) VALUES (2.34567890)

SELECT *
FROM #temp


SELECT
convert(numeric(18,8), -1) * SUM(qnt) as s1
, 1 * SUM(qnt) as s2
, -SUM(qnt) as s3
, SUM((-1)*qnt) as s4
into t
FROM #temp

DROP TABLE #temp


формирует таблицу
[s1] [numeric](38, 6) NULL,
[s2] [numeric](38, 6) NULL,
[s3] [numeric](38, 8) NULL,
[s4] [numeric](38, 8) NULL

таким образом логика убита напрочь )
14 янв 13, 07:10    [13764290]     Ответить | Цитировать Сообщить модератору
 Re: Почему в умноженная сумма на -1 округленяется до 6 знаков?  [new]
invm
Member

Откуда: Москва
Сообщений: 9400
rpuLLIa
таким образом логика убита напрочь )
SUM возвращает decimal(38, s)
BOL
* The result precision and scale have an absolute maximum of 38. When a result precision is greater than 38, the corresponding scale is reduced to prevent the integral part of a result from being truncated.
14 янв 13, 10:31    [13764904]     Ответить | Цитировать Сообщить модератору
 Re: Почему в умноженная сумма на -1 округленяется до 6 знаков?  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
convert(numeric(18,8), -1) * SUM(qnt) as s1

SUM(qnt) - это будет значение numeric(38, s), т.е. в нашем случае numeric(38, 8) (см. статью по функции sum).
для всего выражения получим:
p = 18 + 38 +1 = 57
s = 8 + 8 = 16

в соответствии с:
When a result precision is greater than 38, the corresponding scale is reduced to prevent the integral part of a result from being truncated.

результирующий scale уменьшается. но уменьшается оно не более чем до 6 (если суммарный scale до уменьшения меньше 6 - то он просто не уменьшается). прямо, к сожалению, эти правила не расписаны (я не видел, по крайней мере): как видно, просто сказано что scale is reduced, а как именно reduced в подробностях не разъяснено, но фактически, видимо, так.

итого получаем то самое 38, 6

, 1 * SUM(qnt) as s2

аналогично - после умножения получаем scale уменьшенный до 6.

, -SUM(qnt) as s3

а вот унарный "-" дает тот же тип, что у исходного выражения - numeric(38, 8)

, SUM((-1)*qnt) as s4

(-1)*qnt даст numeric(20, 8), после применения sum получаем numeric(38, 8)

как-то вот так.

зы: для проверки типа данных выражения создавать таблицу не обязательно - можно использовать функцию sql_variant_property.
14 янв 13, 10:51    [13765033]     Ответить | Цитировать Сообщить модератору
 Re: Почему в умноженная сумма на -1 округленяется до 6 знаков?  [new]
rpuLLIa
Member

Откуда:
Сообщений: 23
daw,

Спасибо за то что есть, досадно что не разжовано в официаьлной документации. За зы тоже спасибо )
14 янв 13, 11:37    [13765356]     Ответить | Цитировать Сообщить модератору
 Re: Почему в умноженная сумма на -1 округленяется до 6 знаков?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37053
Просто привыкайте смотреть функцией sql_variant_property, что получается после неявных преобразований. Иногда это весело и познавательно.
14 янв 13, 12:37    [13765848]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить