简体   繁体   English

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?

I know there are many integer division questions on StackOverflow, but I did not see this one. 我知道StackOverflow上有很多整数除法问题,但我没有看到这个问题。

Similar to many programming languages, PostgreSQL performs integer division if both operands are integers. 与许多编程语言类似,如果两个操作数都是整数,PostgreSQL会执行整数除法。

If one has: 如果有:

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

Then to get what one intends, one must cast COUNT(DISTINCT(bc.book_id)) to a non-integer number type. 然后为了获得想要的东西,必须将COUNT(DISTINCT(bc.book_id))转换为非整数数字类型。 If one does not do so, then Postgres, similar to many programming languages, does integer division which is unlikely to give what one wants as a result. 如果没有这样做,那么Postgres就像许多编程语言一样,会进行整数除法,因此不太可能给出想要的结果。

Postgres supports two syntaxes for doing this cast: Postgres支持两种用于执行此转换的语法:

CAST( value AS type )

for example: 例如:

CAST( COUNT(DISTINCT(bc.book_id)) AS DOUBLE PRECISION )

It also supports the syntax: 它还支持语法:

value::type

for example: 例如:

COUNT(DISTINCT(bc.book_id))::decimal

Both syntaxes work, personally I prefer the one using CAST because it is more explicit (I think explicit is good). 两种语法都有效,我个人更喜欢使用CAST语法,因为它更明确(我认为显式是好的)。 Others may prefer value::type because it is expressive yet terse -- shorter is often (up to a limit) better. 其他人可能更喜欢value::type因为它具有表现力而且简洁 - 更短的通常(达到极限)更好。

My question is about the number type to use. 我的问题是关于要使用的数字类型。

In casting COUNT(DISTINCT(bc.book_id)) to a non-integer number type, Postgres gives the following types: 在将COUNT(DISTINCT(bc.book_id))转换为非整数数字类型时,Postgres提供以下类型:

  • decimal
  • numeric
  • real
  • double precision

In my query I chose DOUBLE PRECISION . 在我的查询中,我选择了DOUBLE PRECISION

I am wondering, specifically in the case of division, but also in any other context where one might need to cast an integer number type in PostgreSQL to a non-integer number type, which of the four choices is the best one and why? 我想知道,特别是在除法的情况下,但也在任何其他可能需要将PostgreSQL中的整数类型转换为非整数类型的上下文中,四个选项中哪一个是最好的,为什么?

decimal and numeric are synonyms, so there is one less choice. decimalnumeric是同义词,因此少选择一个。

This is the proper type if you either need very high precision (use numeric without any type modifiers) or if you want to round to a certain number of decimal positions (use numeric(20,2) for two decimal positions). 如果您需要非常高的精度(使用numeric而不使用任何类型修饰符)或者您想要舍入到一定数量的小数位(对于两个小数位使用numeric(20,2) ,这是正确的类型。

This data type is precise, but slow, because it is a “binary coded decimal” type. 此数据类型是精确的,但速度很慢,因为它是“二进制编码的十进制”类型。

real and double precision are 4-byte and 8-byte floating point numbers, fast but with rounding errors and limited precision. realdouble precision是4字节和8字节浮点数,速度快但有舍入误差和精度有限。

Never use real , it has very low precision. 从不使用real ,它具有非常低的精度。

In most practical applications it shouldn't matter which of the two remaining types you use for that specific purpose. 在大多数实际应用中,您为此特定目的使用的其余两种类型中的哪一种无关紧要。

Using the CAST syntax has the advantage that it complies with the standard. 使用CAST语法的优点是它符合标准。

Remark: DISTINCT(col) is syntactically correct, but misleading, because it is not a function. 备注: DISTINCT(col)在语法上是正确的,但有误导性,因为它不是一个函数。 Write DISTINCT col instead. DISTINCT col

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM