postgresql retourne 0 si la valeur renvoyée est null

J’ai une requête qui renvoie avg (prix)

select avg(price) from( select *, cume_dist() OVER (ORDER BY price desc) from web_price_scan where listing_Type='AARM' and u_kbalikepartnumbers_id = 1000307 and (EXTRACT(Day FROM (Now()-dateEnded)))*24 ( select avg(price)* 0.50 from(select *, cume_dist() OVER (ORDER BY price desc) from web_price_scan where listing_Type='AARM' and u_kbalikepartnumbers_id = 1000307 and (EXTRACT(Day FROM (Now()-dateEnded)))*24 < 48 )g where cume_dist < 0.50 ) and price<( select avg(price)*2 from( select *, cume_dist() OVER (ORDER BY price desc) from web_price_scan where listing_Type='AARM' and u_kbalikepartnumbers_id = 1000307 and (EXTRACT(Day FROM (Now()-dateEnded)))*24 < 48 )d where cume_dist  5 

comment le faire retourner 0 si aucune valeur n’est disponible?

utiliser la coalescence

 COALESCE(value [, ...]) 
 The COALESCE function returns the first of its arguments that is not null. Null is returned only if all arguments are null. It is often used to substitute a default value for null values when data is resortingeved for display. 

Modifiez l’exemple de la COALESCE avec votre requête:

 SELECT AVG( price ) FROM( SELECT *, cume_dist() OVER ( ORDER BY price DESC ) FROM web_price_scan WHERE listing_Type = 'AARM' AND u_kbalikepartnumbers_id = 1000307 AND ( EXTRACT( DAY FROM ( NOW() - dateEnded ) ) ) * 24 < 48 AND COALESCE( price, 0 ) > ( SELECT AVG( COALESCE( price, 0 ) )* 0.50 FROM ( SELECT *, cume_dist() OVER ( ORDER BY price DESC ) FROM web_price_scan WHERE listing_Type='AARM' AND u_kbalikepartnumbers_id = 1000307 AND ( EXTRACT( DAY FROM ( NOW() - dateEnded ) ) ) * 24 < 48 ) g WHERE cume_dist < 0.50 ) AND COALESCE( price, 0 ) < ( SELECT AVG( COALESCE( price, 0 ) ) *2 FROM( SELECT *, cume_dist() OVER ( ORDER BY price desc ) FROM web_price_scan WHERE listing_Type='AARM' AND u_kbalikepartnumbers_id = 1000307 AND ( EXTRACT( DAY FROM ( NOW() - dateEnded ) ) ) * 24 < 48 ) d WHERE cume_dist < 0.50) )s HAVING COUNT(*) > 5 

IMHO COALESCE ne doit pas être utilisé avec AVG car il modifie la valeur. NULL signifie non connu et rien d’autre. Ce n’est pas comme si vous l’utilisiez dans SUM . Dans cet exemple, si nous remplaçons AVG par SUM , le résultat n’est pas déformé. Ajouter 0 à une sum ne fait de mal à personne mais calculer une moyenne avec 0 pour les valeurs inconnues, vous n’obtenez pas la moyenne réelle.

Dans ce cas, j’appendais le price IS NOT NULL dans la clause WHERE pour éviter ces valeurs inconnues.

(cette réponse a été ajoutée pour fournir des exemples plus courts et plus génériques à la question – sans inclure tous les détails spécifiques à chaque cas dans la question initiale).


Il y a deux “problèmes” distincts ici, le premier est si une table ou une sous-requête n’a pas de lignes, la seconde est s’il y a des valeurs NULL dans la requête.

Pour toutes les versions que j’ai testées, postgres et mysql ignoreront toutes les valeurs NULL lors du calcul de la moyenne, et retourneront NULL s’il n’y a rien à la moyenne. Cela a généralement un sens, car NULL doit être considéré comme “inconnu”. Si vous voulez remplacer cela, vous pouvez utiliser la coalescence (comme suggéré par Luc M).

 $ create table foo (bar int); CREATE TABLE $ select avg(bar) from foo; avg ----- (1 row) $ select coalesce(avg(bar), 0) from foo; coalesce ---------- 0 (1 row) $ insert into foo values (3); INSERT 0 1 $ insert into foo values (9); INSERT 0 1 $ insert into foo values (NULL); INSERT 0 1 $ select coalesce(avg(bar), 0) from foo; coalesce -------------------- 6.0000000000000000 (1 row) 

bien sûr, “from foo” peut être remplacé par “from (… n’importe quelle logique compliquée ici …) comme foo”

Maintenant, la ligne NULL de la table doit-elle être considérée comme 0? Ensuite, la fusion doit être utilisée dans l’appel avg.

 $ select coalesce(avg(coalesce(bar, 0)), 0) from foo; coalesce -------------------- 4.0000000000000000 (1 row)