Pet*_*tch 4 postgresql precision integer casting division
我知道 StackOverflow 上有很多整数除法问题,但我没有看到这个。
与许多编程语言类似,如果两个操作数都是整数,PostgreSQL 会执行整数除法。
如果有:
SELECT s.id AS student_id,
COUNT(DISTINCT(bc.book_id)) / COUNT(c.id) AS average_books_per_class
FROM student s
LEFT JOIN class c
ON c.student_id = s.id
LEFT JOIN book_class bc
ON bc.class_id = c.id
GROUP BY s.id
Run Code Online (Sandbox Code Playgroud)
然后为了得到一个人的意图,必须COUNT(DISTINCT(bc.book_id))转换为非整数类型。如果不这样做,则 Postgres 与许多编程语言类似,会进行整数除法,这不太可能得到人们想要的结果。
Postgres 支持两种语法来执行此转换:
CAST( value AS type )
Run Code Online (Sandbox Code Playgroud)
例如:
CAST( COUNT(DISTINCT(bc.book_id)) AS DOUBLE PRECISION )
Run Code Online (Sandbox Code Playgroud)
它还支持以下语法:
value::type
Run Code Online (Sandbox Code Playgroud)
例如:
COUNT(DISTINCT(bc.book_id))::decimal
Run Code Online (Sandbox Code Playgroud)
两种语法都有效,我个人更喜欢使用一种,CAST因为它更明确(我认为明确的很好)。其他人可能更喜欢value::type它,因为它富有表现力但简洁——通常(在一定限度内)越短越好。
我的问题是关于要使用的数字类型。
在转换COUNT(DISTINCT(bc.book_id))为非整数类型时,Postgres 提供以下类型:
decimalnumericrealdouble precision在我的查询中,我选择了DOUBLE PRECISION.
我想知道,特别是在除法的情况下,以及在任何其他可能需要将 PostgreSQL 中的整数类型转换为非整数类型的情况下,四种选择中哪一种是最好的,为什么?
decimal和numeric是同义词,所以少了一个选择。
如果您需要非常高的精度(numeric不使用任何类型修饰符),或者您想四舍五入到一定数量的小数位(numeric(20,2)用于两个小数位),这是正确的类型。
这种数据类型很精确,但速度很慢,因为它是“二进制编码的十进制”类型。
real并且double precision是 4 字节和 8 字节浮点数,速度快,但有舍入误差和有限的精度。
永远不要使用real,它的精度很低。
在大多数实际应用中,为特定目的使用剩余的两种类型中的哪一种并不重要。
使用CAST语法的优点是符合标准。
备注:DISTINCT(col)在语法上是正确的,但具有误导性,因为它不是一个函数。改写DISTINCT col。
| 归档时间: |
|
| 查看次数: |
1029 次 |
| 最近记录: |