Имя: Пароль:
1C
 
Округление поля в результате запроса
0 sqr4
 
23.10.19
15:47
Сам запрос

ВЫБРАТЬ
    УчетЗатратОстатки.АналитикаУчетаЗатрат,
    УчетЗатратОстатки.СтоимостьОстаток / УчетЗатратОстатки.КоличествоОстаток КАК Поле1,
    Выразить(11000061.87 Как Число(15,2))/Выразить(45780.000 Как Число(15,3)) Как поле2,
    УчетЗатратОстатки.КоличествоОстаток,
    УчетЗатратОстатки.СтоимостьОстаток
ИЗ
    РегистрНакопления.УчетЗатратРегл.Остатки(&ДатаДокумента, АналитикаУчетаЗатрат = &Аналитика) КАК УчетЗатратОстатки


Поле 1 = 240,280949
Поле 2 = 240,2809495412844036697247

Не могу понять почему такая разница в округлении, прошу помощи.
1 sqr4
 
23.10.19
15:48
Конфа КА 1 последняя
2 ДенисЧ
 
23.10.19
15:54
А зачем ты это в запросе делаешь?
3 mc lammer
 
23.10.19
15:55
быть может в СУБД типы данных  СтоимостьОстаток  и КоличествоОстаток  не соответствуют Число(15,2) и Число(15,3),  и результат вычисления поэтому различается.  надо смотреть трассировку запроса.
4 sqr4
 
23.10.19
16:04
(2) это не я делаю, я упростил запрос, это разработчики КА1
5 hhhh
 
23.10.19
16:09
(4) Надо Выразить на всё выражение. А то как у вас Выразить / Выразить - это получается без округления.
6 sqr4
 
23.10.19
16:12
(5) А вторая строка с округлением?
7 sqr4
 
23.10.19
16:14
Тут тоже УчетЗатратОстатки.СтоимостьОстаток / УчетЗатратОстатки.КоличествоОстаток КАК Поле1 нет округления, но результат выводит только три цифры, уменьшая разрядность чисел до таких
Выразить(11000061.87 Как Число(8,0))/Выразить(45780.000 Как Число(8,0)) Как поле2,
ПОлучил в поле 2 такой результат 240,28095238095238095 опять же неокругленный.
8 sqr4
 
23.10.19
16:25
А вот такое
Выразить(11000061.87 Как Число(38,10))/Выразить(45780.000 Как Число(38,10)) Как поле2,
Поле2 = 240,280949
9 sqr4
 
23.10.19
16:27
Подсказку взял отсюда
https://docs.microsoft.com/ru-ru/sql/t-sql/data-types/precision-scale-and-length-transact-sql?view=sql-server-ver15

При выполнении операций умножения и деления требуется precision - scale разрядов для хранения целой части результата. Масштаб может уменьшаться согласно приведенным ниже правилам.
Итоговый масштаб уменьшается до min(scale, 38 - (precision-scale)), если целая часть короче 32 разрядов, так как он не может быть больше 38 - (precision-scale). В этом случае результат может округляться.
Масштаб не изменяется, если он меньше 6 и если целая часть длиннее 32 разрядов. В этом случае может возникнуть ошибка переполнения, если число не помещается в decimal(38, scale).
Масштаб будет задан равным 6, если он больше 6 и если целая часть длиннее 32 разрядов. В этом случае уменьшаются как целая часть, так и масштаб, и итоговым типом будет decimal(38,6). Результат может округляться до 6 десятичных знаков, либо может возникнуть ошибка переполнения, когда целая часть не помещается в 32 разряда.
10 sqr4
 
23.10.19
16:31
Где на ИТС об этом почитать?
11 Chameleon1980
 
23.10.19
16:34
Ты делишь округленное на округленное, но результат не окркгляешь.
12 sqr4
 
23.10.19
16:40
(11) в первом случае тоже, но результат разный поэтому и задал вопрос. В ходе параллельного гуглежа нащупал в чем дело. Теперь бы хотелось документированное описание почитать, пока не нашел
13 Chameleon1980
 
23.10.19
16:49
Что ожидал в (8)?
Оберни все выражение в выразить какое нужно ещё раз
14 Chameleon1980
 
23.10.19
16:51
240,28094954128
?
15 sqr4
 
23.10.19
16:53
(14) мне нужно первое, которое округленное
16 sqr4
 
23.10.19
16:54
(13) У меня цель разобраться в том почему так получается
17 Chameleon1980
 
23.10.19
17:14
(16) бля. получается так, а ожидал что?
18 Chameleon1980
 
23.10.19
17:16
(15) еще раз блин.
Все округли теперь

Выразить(11000061.87 /45780.000 Как Число(8,0)) Как поле2
19 Chameleon1980
 
23.10.19
17:17
или
если ты хочешь сначала округлить операнды:

Выразить(Выразить(11000061.87 Как Число(8,0))/Выразить(45780.000 Как Число(8,0) как ЧИсло(15,0)) Как поле2
20 novichok79
 
23.10.19
17:19
какая СУБД?
21 sqr4
 
23.10.19
17:19
(18) да нахера мне округлять, у меня бл.ть два однотипных выражения
УчетЗатратОстатки.СтоимостьОстаток / УчетЗатратОстатки.КоличествоОстаток КАК Поле1, (тут Стоимость остаток = 11000061.87 и количество остаток = 45780.000)
11000061.87 /45780.000 Как поле2,
В итоге
Поле 1 = 240,280949
Поле 2 = 240,2809495412844036697247
Вопрос почему, вопрос почемуууууу. Мне не надо приводить к общему целому через выразить. Мне надо понять как это работает в общем случае.
22 novichok79
 
23.10.19
17:20
если MS SQL, то если у тебя используется в делении выразить, то надо выражать и результат тоже.
году в 2011-м сталкивался с этим. возможно в 1С пофиксили уже.
23 novichok79
 
23.10.19
17:24
это глюк, если что.
24 sqr4
 
23.10.19
17:27
(20) MS SQL тут понятно что разрядность этих полей превышает вот это
Масштаб будет задан равным 6, если он больше 6 и если целая часть длиннее 32 разрядов. В этом случае уменьшаются как целая часть, так и масштаб, и итоговым типом будет decimal(38,6). Результат может округляться до 6 десятичных знаков, либо может возникнуть ошибка переполнения, когда целая часть не помещается в 32 разряда.

Наверно имеет смысл посмотреть, каким образом строится выборка из виртуальной таблицы остатков в плане разрядности полей.
25 sqr4
 
23.10.19
17:28
Но где найти инфу про это и есть ли она. Как по мне не похоже на глюк в моем случае.
причем если я использую виртуальную таблицу остатков и оборотов, то результат другой поле 1 = 240,2809495412844036697247
26 Chameleon1980
 
23.10.19
17:30
(21) Ну пардон. я чет думал ты думаешь почему не округляет.
вижу теперь
интересно
27 sqr4
 
23.10.19
17:32
Ну наверно на самом деле ответ в (3)
28 kabanoff
 
23.10.19
17:56
(0) Потому что на скуле это выглядит вот так:


exec sp_executesql N'SELECT
T1.Fld4500RRef,
T1.Fld4506RRef,
T1.Fld4511Turnover_,
T1.Fld4512Turnover_,
6.032432432432432432432432432,
(CAST(T1.Fld4512Turnover_ AS NUMERIC(27, 8)) / (T1.Fld4511Turnover_))
FROM (SELECT
T2._Fld4500RRef AS Fld4500RRef,
T2._Fld4506RRef AS Fld4506RRef,
CAST(SUM(T2._Fld4512) AS NUMERIC(21, 2)) AS Fld4512Turnover_,
CAST(SUM(T2._Fld4511) AS NUMERIC(21, 3)) AS Fld4511Turnover_
FROM dbo._AccumRg4499 T2
WHERE T2._Period >= P1 AND T2._Period <= @P2 AND T2._Active = 0x01 AND (((T2._Fld4500RRef = @P3) AND (T2._Fld4506RRef = @P4)))
GROUP BY T2._Fld4500RRef,
T2._Fld4506RRef
HAVING (CAST(SUM(T2._Fld4512) AS NUMERIC(21, 2))) <> 0.0 OR (CAST(SUM(T2._Fld4511) AS NUMERIC(21, 3))) <> 0.0) T1',N'P1 datetime2(3),@P2 datetime2(3),@P3 varbinary(16),@P4 varbinary(16)','2019-10-20 00:00:00','2019-10-20 23:59:59',0xA12F000C298B1BA711E47C48FD50C510,0x8301000C298B1BA711E4AFA4A0B8C1C0


Исходный запрос:

ВЫБРАТЬ
    ПродажиОбороты.Номенклатура КАК Номенклатура,
    ПродажиОбороты.Подразделение КАК Подразделение,
    ПродажиОбороты.КоличествоОборот КАК КоличествоОборот,
    ПродажиОбороты.СтоимостьОборот КАК СтоимостьОборот,
    1116.00 / 185.000 КАК Поле1,
    ПродажиОбороты.СтоимостьОборот / ПродажиОбороты.КоличествоОборот КАК Поле2
ИЗ
    РегистрНакопления.Продажи.Обороты(
            &Начало,
            &Конец,
            Период,
            Номенклатура = &Номенклатура
                И Подразделение = &Подразделение) КАК ПродажиОбороты