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 有足够空间容纳该整数类型的最大位数时才允许。BI
GINT 需要左侧保留 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 列作为分区键比浮点数更可靠,因为其目录名称与数值完全对应,不会出现浮点数表示不精确导致的目录名误差。