Ответ не имеет ничего общего с int
типом данных
- Литерал
0.5
имеет тип данных decimal(1,1)
- Применение
CEILING
к decimal(p,s)
возвращает результат типа decimal(p,0)
- Применение
SUM
к decimal(p,s)
возвращает результат типа decimal(38,s)
- со смешанным выражением
CASE
, которое может вернуть decimal(p1,s1)
или decimal(p2,s2)
результат будет использовать те же правила, что и при UNION
-инге этих типов данных и имеют точность (*
) max(s1, s2) + max(p1-s1, p2-s2)
и масштаб max(s1, s2)
*
Точность и масштаб результата имеют абсолютный максимум 38. Когда точность результата больше 38, она уменьшается до 38, а соответствующий масштаб уменьшается, чтобы попытаться предотвратить интегральную часть результатаусеченный.( source )
Таким образом, ваш столбец h
имеет тип данных decimal(2,1)
, тип данных при применении SUM
равен decimal(38,1)
, тип данных CEILING
применяется к этому decimal(38,0)
.Затем вы используете это в выражении CASE
с decimal(1,1)
max(s1, s2) + max(p1-s1, p2-s2)
max( 0, 1) + max( 38, 0) = 1 + 38 = 39
И
max(s1, s2) = max(0, 1) = 1
Таким образом, желаемый тип данных результата будет decimal(39,1)
.Это больше 38, так что вы получите уменьшение масштаба, описанное выше, и получите decimal(38,0)
- 0.5
округляется до 1
при приведении к этому типу данных.
Если вы предпочитаете сохранить точностьконечный результат, который вы можете использовать
case when 1=1 then 0.5 else CAST(ceiling(sh) AS decimal(38,1)) end
При этом существует дополнительный риск переполнения, но для того, чтобы его ударить, к сумме нужно добавить одно из следующих значений
9999999999999999999999999999999999999.5
9999999999999999999999999999999999999.6
9999999999999999999999999999999999999.7
9999999999999999999999999999999999999.8
9999999999999999999999999999999999999.9
такой, что SUM
сам вписывается в 38,1
, а CEILING
- нет.