PostgreSQL:在将整数转换为非整数类型以强制在 PostgreSQL 中进行浮点除法时,我应该使用哪种数字类型?
PostgreSQL: When casting an integer to a non-integer type to force floating point division in PostgreSQL, which number type should I use?
我知道 Whosebug 上有很多整数除法题,但是我没有看到这个。
与许多编程语言类似,如果两个操作数都是整数,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
然后为了得到想要的结果,必须将 COUNT(DISTINCT(bc.book_id))
转换为非整数类型。如果不这样做,那么类似于许多编程语言的 Postgres 会进行整数除法,这不太可能给出人们想要的结果。
Postgres 支持两种语法来执行此转换:
CAST( value AS type )
例如:
CAST( COUNT(DISTINCT(bc.book_id)) AS DOUBLE PRECISION )
它还支持语法:
value::type
例如:
COUNT(DISTINCT(bc.book_id))::decimal
两种语法都有效,我个人更喜欢使用 CAST
的语法,因为它更明确(我认为明确的很好)。其他人可能更喜欢 value::type
,因为它既富有表现力又简洁——通常越短(在一定程度上)越好。
我的问题是关于要使用的号码类型。
在将 COUNT(DISTINCT(bc.book_id))
转换为非整数类型时,Postgres 给出了以下类型:
decimal
numeric
real
double precision
在我的查询中我选择了DOUBLE PRECISION
。
我想知道,特别是在除法的情况下,以及在可能需要将 PostgreSQL 中的整数类型转换为非整数类型的任何其他情况下,四种选择中哪一种是最好的一,为什么?
decimal
和numeric
是同义词,少了一个选择
如果您需要非常高的精度(使用不带任何类型修饰符的 numeric
)或者如果您希望四舍五入到一定数量的小数(使用 numeric(20,2)
两位小数)。
这种数据类型是精确的,但速度慢,因为它是一种“二进制编码的十进制”类型。
real
和 double precision
是 4 字节和 8 字节的浮点数,速度快但有舍入误差和精度有限。
永远不要使用real
,它的精度很低。
在大多数实际应用中,为特定目的使用剩余两种类型中的哪一种并不重要。
使用CAST
语法的好处是符合标准。
备注:DISTINCT(col)
在语法上是正确的,但会误导,因为它不是一个函数。改为写 DISTINCT col
。
我知道 Whosebug 上有很多整数除法题,但是我没有看到这个。
与许多编程语言类似,如果两个操作数都是整数,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
然后为了得到想要的结果,必须将 COUNT(DISTINCT(bc.book_id))
转换为非整数类型。如果不这样做,那么类似于许多编程语言的 Postgres 会进行整数除法,这不太可能给出人们想要的结果。
Postgres 支持两种语法来执行此转换:
CAST( value AS type )
例如:
CAST( COUNT(DISTINCT(bc.book_id)) AS DOUBLE PRECISION )
它还支持语法:
value::type
例如:
COUNT(DISTINCT(bc.book_id))::decimal
两种语法都有效,我个人更喜欢使用 CAST
的语法,因为它更明确(我认为明确的很好)。其他人可能更喜欢 value::type
,因为它既富有表现力又简洁——通常越短(在一定程度上)越好。
我的问题是关于要使用的号码类型。
在将 COUNT(DISTINCT(bc.book_id))
转换为非整数类型时,Postgres 给出了以下类型:
decimal
numeric
real
double precision
在我的查询中我选择了DOUBLE PRECISION
。
我想知道,特别是在除法的情况下,以及在可能需要将 PostgreSQL 中的整数类型转换为非整数类型的任何其他情况下,四种选择中哪一种是最好的一,为什么?
decimal
和numeric
是同义词,少了一个选择
如果您需要非常高的精度(使用不带任何类型修饰符的 numeric
)或者如果您希望四舍五入到一定数量的小数(使用 numeric(20,2)
两位小数)。
这种数据类型是精确的,但速度慢,因为它是一种“二进制编码的十进制”类型。
real
和 double precision
是 4 字节和 8 字节的浮点数,速度快但有舍入误差和精度有限。
永远不要使用real
,它的精度很低。
在大多数实际应用中,为特定目的使用剩余两种类型中的哪一种并不重要。
使用CAST
语法的好处是符合标准。
备注:DISTINCT(col)
在语法上是正确的,但会误导,因为它不是一个函数。改为写 DISTINCT col
。