杂记:PostgreSQL 除法的坑

还是 Oracle 转 PostgreSQl 的坑

整数除

假设有 Decimal(12,2) 金额=1234, int 费率=5 (表示5%)
要计算 费率=金额*费率/100,那么 Oracle 下面的表达式都没问题

with T as (
     select CAST(1234 AS DECIMAL(12,2)) A, CAST(5 AS int) R from DUAL
)
select round(A * R / 100, 2) expr1, round(A * (R / 100), 2) expr2 from T

返回

expr1expr2
61.761.7

然后对应到 PostgreSQL 中

with T as (
     select 1234 ::numeric(12,2) A,  5 ::int R
)
select round(A * R / 100, 2) expr1, round(A * (R / 100), 2) expr2 from T

返回

expr1expr2
61.70.00

瞧,expr2 变成了零,因为在 PostgreSQL 中 5 / 100 = 0 没有小数!
谁TMD整除会比普通除还常用,设计 PostgreSQL 语法的人脑子有病!

小数除

无论是 Oracle 自动转类型还是 PostgreSQL 强制转类型保证运算正确,计算中间最常见中间类型是 Decimal/Numeric
在 Oracle 中模拟一下

with T as (
     select cast(1234 as numeric) A,  cast(10 as numeric) R from DUAL
)
select R / 100 expr1, A * (R / 100) expr2 from T

返回

expr1expr2
0.1123.4

然后对应到 PostgreSQL 中

with T as (
     select 1234 ::numeric A,  10 ::numeric R
)
select R / 100 expr1, A * (R / 100) expr2 from T

返回

expr1expr2
0.10000000000000000000123.40000000000000000000

瞧,小数除法可能会多出好多无用0,并且会随加减乘等运算蔓延。通过 JDBC 字段类型对应到 BigDecimal,也会保留尾部的无用0进行显示;用 round() 只能固定小数位、和原样一致要用 trim_scale

select trim_scale(R / 100) expr1, trim_scale(A * (R / 100)) expr2 from T

返回

expr1expr2
0.1123.4
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值