Как округлить среднее значение до 2 знаков после запятой в PostgreSQL?
Я использую PostgreSQL через Ruby gem 'sequel'.
Я пытаюсь округлить до двух знаков после запятой.
вот мой код:
SELECT ROUND(AVG(some_column),2)
FROM table
Я получаю следующую ошибку:
PG::Error: ERROR: function round(double precision, integer) does
not exist (Sequel::DatabaseError)
Я не получаю ошибку, когда я запускаю следующий код:
SELECT ROUND(AVG(some_column))
FROM table
кто-нибудь знает, что я делаю неправильно?
5 ответов:
PostgreSQL не определяет
round(double precision, integer). По причинам @Catcall объясняет в комментариях, версия раунда, который принимает точность доступна только дляnumeric.regress=> SELECT round( float8 '3.1415927', 2 ); ERROR: function round(double precision, integer) does not exist regress=> \df *round* List of functions Schema | Name | Result data type | Argument data types | Type ------------+--------+------------------+---------------------+-------- pg_catalog | dround | double precision | double precision | normal pg_catalog | round | double precision | double precision | normal pg_catalog | round | numeric | numeric | normal pg_catalog | round | numeric | numeric, integer | normal (4 rows) regress=> SELECT round( CAST(float8 '3.1415927' as numeric), 2); round ------- 3.14 (1 row)(в приведенном выше, обратите внимание, что
float8это просто сокращенный псевдоним дляdouble precision. Вы можете видеть, что PostgreSQL расширяет его в выводе).вы должны привести значение, которое будет округлено до
numericиспользовать форму с двумя аргументамиround. Просто добавьте::numericдля стенографии, напримерround(val::numeric,2).
если вы форматируете для отображения пользователю, не используйте
round. Используйтеto_char(см.: функции форматирования данных типа в руководстве), который позволяет задать формат и дает вамtextрезультат, который не зависит от того, какие странности ваш клиентский язык может сделать сnumericзначения. Например:regress=> SELECT to_char(float8 '3.1415927', 'FM999999999.00'); to_char --------------- 3.14 (1 row)
to_charокруглит числа для вас как часть форматирования. ЭлементFMпрефикс сообщаетto_charчто вы не хочу никаких прокладок с ведущими пробелами.
попробуйте также старый синтаксис для литья,
SELECT ROUND(AVG(some_column)::numeric,2) FROM table;работает с любой версией PostgreSQL.
есть недостаток перегрузок в некоторых функциях PostgreSQL, почему (???): Я думаю, что "это недостаток" (!), но @CraigRinger, @Catcall и команда PostgreSQL согласны с "историческим обоснованием pg".
PS: еще один момент о округлении точность, Регистрация @IanKenney по ответ.
перегрузка как стратегия кастинга
вы можете перегрузка круглая функция с,
CREATE FUNCTION ROUND(float,int) RETURNS NUMERIC AS $$ SELECT ROUND(::numeric,); $$ language SQL IMMUTABLE;теперь ваша инструкция будет работать нормально, попробуйте (после создания) функция
SELECT round(1/3.,4); -- 0.3333 numericно он возвращает числовой тип... Чтобы сохранить первую перегрузку commom-usage, мы можем вернуть тип FLOAT, когда предлагается текстовый параметр,
CREATE FUNCTION ROUND(float, text, int DEFAULT 0) RETURNS FLOAT AS $$ SELECT CASE WHEN ='dec' THEN ROUND(::numeric,)::float -- ... WHEN ='hex' THEN ... WHEN ='bin' THEN... complete! ELSE 'NaN'::float -- like an error message END; $$ language SQL IMMUTABLE;попробовать
SELECT round(1/3.,'dec',4); -- 0.3333 float! SELECT round(2.8+1/3.,'dec',1); -- 3.1 float! SELECT round(2.8+1/3.,'dec'::text); -- need to cast string? pg bug
PS: проверка
\df roundпосле перегрузки, покажет что-то вродеSchema | Name | Result data type | Argument data types ------------+-------+------------------+---------------------------- myschema | round | double precision | double precision, text, int myschema | round | numeric | double precision, int pg_catalog | round | double precision | double precision pg_catalog | round | numeric | numeric pg_catalog | round | numeric | numeric, intThe
pg_catalogфункции по умолчанию, см. руководство по встроенным математическим функциям.
попробуйте с помощью этого:
SELECT to_char (2/3::float, 'FM999999990.00'); -- RESULT: 0.67или просто:
SELECT round (2/3::DECIMAL, 2)::TEXT -- RESULT: 0.67
ошибка: функция round (двойная точность, целое число) не существует
решение: вам нужно addtype cast, то он будет работать
Ex:
round(extract(second from job_end_time_t)::integer,0)
по данным Брайан ответ вы можете сделать это, чтобы ограничить десятичных знаков в запросе. Я конвертирую из км/ч в М / С и отображаю его в диграфах, но когда я сделал это в диграфах, это выглядело странно. Выглядит нормально при выполнении вычисления в запросе вместо этого. Это на postgresql 9.5.1.
select date,(wind_speed/3.6)::numeric(7,1) from readings;
Comments