Je voudrais effectuer la division dans une clause SELECT. Lorsque je joins certaines tables et que j'utilise la fonction d'agrégat, j'ai souvent des valeurs nulles ou nulles comme séparateurs. Pour l'instant, je ne propose que cette méthode pour éviter la division par zéro et les valeurs nulles.
(CASE(COALESCE(COUNT(column_name),1)) WHEN 0 THEN 1
ELSE (COALESCE(COUNT(column_name),1)) END)
Je me demande s'il y a une meilleure façon de faire cela?
Puisque count()
NE RETOURNE JAMAIS NULL
(contrairement aux autres fonctions d'agrégat), il vous suffit d'attraper le cas 0
(qui est le seul cas problématique de toute façon):
CASE count(column_name)
WHEN 0 THEN 1
ELSE count(column_name)
END
Citation du manuel sur les fonctions d'agrégat:
Il est à noter que sauf pour
count
, ces fonctions renvoient un Valeur nulle quand aucune ligne n'est sélectionnée.
Vous pouvez utiliser la fonction NULLIF, 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
Je réalise que c’est une vieille question, mais une autre solution consisterait à utiliser la fonction greatest:
greatest( count(column_name), 1 ) -- NULL and 0 are valid argument values
Remarque: .__ Ma préférence serait de renvoyer une valeur NULL, comme dans la réponse de Erwin et Yuriy, ou de résoudre ce problème de manière logique en détectant que la valeur est 0
avant l'opération de division et renvoyer 0
. Sinon, les données risquent d'être mal représentées en utilisant 1
.
Une autre solution en évitant seulement la division par zéro, en changeant la division par 1
select column + (column = 0)::integer;
Si vous voulez que le diviseur soit égal à 1 lorsque le compte est égal à zéro:
count(column_name) + 1 * (count(column_name) = 0)::integer
La distribution de true
à integer
est 1.