113 votes

Éviter la division par zéro dans PostgreSQL

J'aimerais effectuer une division dans une clause SELECT. Lorsque je joins des tables et que j'utilise la fonction d'agrégation, j'ai souvent des valeurs nulles ou zéro comme diviseurs. Pour l'instant, je n'ai trouvé que cette méthode pour éviter la division par des valeurs nulles et zéro.

(CASE(COALESCE(COUNT(column_name),1)) WHEN 0 THEN 1
ELSE (COALESCE(COUNT(column_name),1)) END) 

Je me demande s'il existe une meilleure façon de procéder ?

294voto

Yuriy Galanter Points 21066

Vous pouvez utiliser NULLIF fonction, par exemple

something/NULLIF(column_name,0)

Si la valeur de column_name est 0 - le résultat de l'expression entière sera NULL

58voto

Erwin Brandstetter Points 110228

Desde count() ne revient jamais NULL (contrairement à d'autres fonctions d'agrégation), il suffit d'attraper la fonction 0 (qui est le seul cas problématique de toute façon). Donc, votre question est simplifiée :

CASE count(column_name)
   WHEN 0 THEN 1
   ELSE count(column_name)
END

Ou plus simple encore, avec NULLIF() , comme Yuriy a fourni .

Citer le manuel sur les fonctions d'agrégation :

Il convient de noter qu'à l'exception de count ces fonctions renvoient un valeur nulle si aucune ligne n'est sélectionnée.

50voto

vol7ron Points 11270

Je réalise que c'est une vieille question, mais une autre solution serait d'utiliser la fonction le plus grand fonction :

greatest( count(column_name), 1 )  -- NULL and 0 are valid argument values

Nota: Ma préférence serait soit de retourner un NULL, comme dans la réponse d'Erwin et de Yuriy, soit de résoudre ce problème logiquement en détectant que la valeur est 0 avant l'opération de division, et en retournant 0 . Dans le cas contraire, les données peuvent être déformées en utilisant 1 .

9voto

manvel Points 39

Une autre solution évitant la division par zéro, en remplaçant par 1

select column + (column = 0)::integer;

3voto

Clodoaldo Neto Points 26723

Si vous voulez que le diviseur soit à 1 quand le compte est à zéro :

count(column_name) + 1 * (count(column_name) = 0)::integer

Les acteurs de true a integer est de 1.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X