DECIMAL

最近更新时间:2026-05-06 16:28:12

我的收藏
DECIMAL 是一种具有固定精度(Precision)和标度(Scale)的数值数据类型。它非常适合存储和计算需要精确结果的数值,例如货币、科学计量等。

语法与定义

DECIMAL[(precision[, scale])]
Precision(精度):表示该数值的总位数(不含小数点)。
范围:1 到 38。
默认值:9。
Scale(标度):表示小数点后的位数。
必须小于或等于精度。
默认值:0。
默认状态:省略参数时,默认为 DECIMAL(9, 0)

范围与极值

取值范围: -10^38+1 10^38−1
最大值:DECIMAL(38, 0) 表示。
最精密小数值:DECIMAL(38, 38) 表示(小数点后 38 位)。其最接近 0 的值为 0.000...1(37 个零),最接近 1 的值为 0.999...(38 个九)。

内存占用

DECIMAL 的内存占用仅由精度(Precision)决定,与标度无关。
精度 (Precision)
内存占用 (In-memory Storage)
1 - 9
4 字节
10 - 18
8 字节
19 - 38
16 字节

算术运算规则

TCHouse-X 的 DECIMAL 运算遵循严格的精度推导公式,最大精度为 38。若推导出的精度超过 38,TCHouse-X 将优先保留至少 6 位小数并进行四舍五入。
运算
结果精度 (Resulting Precision)
结果标度 (Resulting Scale)
加法 / 减法
max(L1, L2) + max(S1, S2) + 1
max(S1, S2)
乘法
P1 + P2 + 1
S1 + S2
除法
L1 + S2 + max(S1 + P2 + 1, 6)
max(S1 + P2 + 1, 6)
取模
min(L1, L2) + max(S1, S2)
max(S1, S2)
说明:
变量定义:
p1, p2:输入值的精度(Precision)。
S1, S2:输入值的标度(Scale)。
L1, L2:输入值的整数部分位数,计算公式为 L = P - S。

类型转换

隐式转换

DECIMAL → DOUBLE/FLOAT:必要时会自动转换,但会丢失精度(故不推荐大量使用浮点型)。
DOUBLE/FLOAT → DECIMAL:禁止隐式转换,必须显式使用 CAST()
整数 → DECIMAL:仅当目标 DECIMAL 有足够空间容纳该整数类型的最大位数时才允许。
BIGINT 需要左侧保留 19 位;INT 10 位;SMALLINT 5 位;TINYINT 3 位。

显式转换

CAST(STRING AS DECIMAL):
如果字符串小数位多于目标标度,将执行四舍五入。
支持科学计数法,如 CAST('1.0e6' AS DECIMAL(32, 0))
CAST(DECIMAL AS TIMESTAMP):返回 Unix 纪元(1970-01-01)之后 N 秒的时间点。在查询展示时,该值会自动转换为当前系统时区对应的本地时间。

与 FLOAT/DOUBLE 的对比

特性
DECIMAL
FLOAT / DOUBLE
精确性
绝对精确(适合金融计算)
不精确,存在舍入误差
性能
运算开销略高
高性能(硬件指令加速)
聚合一致性
结果可重复且稳定
大数据量 SUM/AVG 可能产生微小波动
分区
推荐,目录名与数值严格匹配
不推荐,目录名可能不符合预期

特殊场景注意事项

分区

使用 DECIMAL 列作为分区键比浮点数更可靠,因为其目录名称与数值完全对应,不会出现浮点数表示不精确导致的目录名误差。