J'utilise PostgreSQL via la "suite" de Ruby gem.
J'essaie d'arrondir à deux décimales.
Voici mon code:
SELECT ROUND(AVG(some_column),2)
FROM table
J'obtiens l'erreur suivante:
PG::Error: ERROR: function round(double precision, integer) does
not exist (Sequel::DatabaseError)
Je n'obtiens aucune erreur lorsque j'exécute le code suivant:
SELECT ROUND(AVG(some_column))
FROM table
Quelqu'un sait-il ce que je fais mal?
sql
ruby
postgresql
sequel
user1626730
la source
la source
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
Réponses:
PostgreSQL ne définit pas
round(double precision, integer)
. Pour des raisons expliquées par @Mike Sherrill 'Cat Recall' dans les commentaires, la version de round qui prend une précision n'est disponible que pournumeric
.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)
(Dans ce qui précède, notez qu'il
float8
s'agit simplement d'un alias abrégé pourdouble precision
. Vous pouvez voir que PostgreSQL l'étend dans la sortie).Vous devez convertir la valeur à arrondir
numeric
pour utiliser la forme à deux arguments deround
. Ajoutez juste::numeric
pour la distribution de raccourci, commeround(val::numeric,2)
.Si vous formatez pour l'affichage à l'utilisateur, n'utilisez pas
round
. Utilisezto_char
(voir: fonctions de formatage des types de données dans le manuel), qui vous permet de spécifier un format et vous donne untext
résultat qui n'est pas affecté par les bizarreries que votre langue client pourrait faire avec lesnumeric
valeurs. Par exemple:regress=> SELECT to_char(float8 '3.1415927', 'FM999999999.00'); to_char --------------- 3.14 (1 row)
to_char
arrondira les nombres pour vous dans le cadre du formatage. LeFM
préfixe indiqueto_char
que vous ne voulez pas de remplissage avec des espaces de début.la source
ROUND(CAST(FLOAT8 '3.1415927' AS NUMERIC),2);
, j'obtiens «0.314E1». Et j'ai mon code écritROUND(AVG(val),2)
encore obtenir l'erreur que j'ai décrite dans ma question.ROUND(CAST(FLOAT8 '3.1415927' AS NUMERIC),2);
sur PgAdmin et Ruby. Avec PgAdmin, j'obtiens 3.14, mais avec Ruby (en utilisant la gemme Sequel) j'obtiens '0.314E1'. Je me demande pourquoi c'est ...double
version deround
aurait besoin de retournernumeric
ou (ugh)text
, donc elle pourrait aussi bien prendre unnumeric
argument.Essayez aussi l'ancienne syntaxe pour la diffusion,
SELECT ROUND(AVG(some_column)::numeric,2) FROM table;
fonctionne avec n'importe quelle version de PostgreSQL.
Il y a un manque de surcharge dans certaines fonctions PostgreSQL, pourquoi (???): Je pense que "c'est un manque" (!), Mais @CraigRinger, @Catcall et l'équipe de PostgreSQL sont d'accord sur "la logique historique de pg".
PS: un autre point sur l'arrondi est la précision , vérifiez la réponse de @ IanKenney .
Surcharge comme stratégie de casting
Vous pouvez surcharger la fonction ROUND avec,
CREATE FUNCTION ROUND(float,int) RETURNS NUMERIC AS $$ SELECT ROUND($1::numeric,$2); $$ language SQL IMMUTABLE;
Maintenant, votre instruction fonctionnera correctement, essayez (après la création de la fonction)
SELECT round(1/3.,4); -- 0.3333 numeric
mais il retourne un type NUMERIC ... Pour conserver la première surcharge d'usage commun, on peut retourner un type FLOAT lorsqu'un paramètre TEXT est proposé,
CREATE FUNCTION ROUND(float, text, int DEFAULT 0) RETURNS FLOAT AS $$ SELECT CASE WHEN $2='dec' THEN ROUND($1::numeric,$3)::float -- ... WHEN $2='hex' THEN ... WHEN $2='bin' THEN... complete! ELSE 'NaN'::float -- like an error message END; $$ language SQL IMMUTABLE;
Essayer
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: vérifier
\df round
après les surcharges, affichera quelque chose comme,Les
pg_catalog
fonctions sont celles par défaut, voir le manuel des fonctions mathématiques intégrées .la source
Essayez avec ceci:
SELECT to_char (2/3::float, 'FM999999990.00'); -- RESULT: 0.67
Ou simplement:
SELECT round (2/3::DECIMAL, 2)::TEXT -- RESULT: 0.67
la source
vous pouvez utiliser la fonction ci-dessous
SELECT TRUNC(14.568,2);
le résultat montrera:
14.56
vous pouvez également convertir votre variable dans le type souhaité:
SELECT TRUNC(YOUR_VAR::numeric,2)
la source
Essayez de convertir votre colonne en une valeur numérique comme:
SELECT ROUND(cast(some_column as numeric),2) FROM table
la source
Selon la réponse de Bryan, vous pouvez le faire pour limiter les décimales dans une requête. Je convertis de km / h en m / s et je l'affiche dans des dygraphes, mais quand je l'ai fait dans des dygraphes, cela avait l'air bizarre. Cela a l'air bien lors du calcul dans la requête. C'est sur postgresql 9.5.1.
select date,(wind_speed/3.6)::numeric(7,1) from readings;
la source
Solution : vous devez ajouter le type de cast, cela fonctionnera
Ex:
round(extract(second from job_end_time_t)::integer,0)
la source
sélectionnez ROUND (SUM (amount) :: numeric, 2) comme total_amount FROM transactions
donne: 200234.08
la source