PostgreSQL: при преобразовании целого числа в нецелочисленный тип для принудительного деления числа с плавающей запятой в PostgreSQL какой тип чисел следует использовать? - PullRequest
1 голос
/ 05 апреля 2019

Я знаю, что в 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

Тогда, чтобы получить то, что он намерен, нужно привести 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 к типу нецелых чисел, какой из четырех вариантов является лучшим и почему?

1 Ответ

3 голосов
/ 05 апреля 2019

decimal и numeric являются синонимами, так что есть еще один выбор.

Это правильный тип, если вам нужна очень высокая точность (используйте numeric без модификаторов типов) или если вы хотите округлить до определенного числа десятичных разрядов (используйте numeric(20,2) для двух десятичных разрядов).

Этот тип данных точный, но медленный, потому что это & ​​ldquo; двоично-десятичное десятичное число & rdquo; тип.

real и double precision - это 4-байтовые и 8-байтовые числа с плавающей запятой, быстрые, но с ошибками округления и ограниченной точностью.

Никогда не используйте real, он имеет очень низкую точность.

В большинстве практических приложений не должно иметь значения, какой из двух оставшихся типов вы используете для этой конкретной цели.

Преимущество использования синтаксиса CAST в том, что он соответствует стандарту.

Примечание: DISTINCT(col) синтаксически правильно, но вводит в заблуждение, потому что это не функция. Напишите DISTINCT col вместо.

...