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 < 48
and price>( 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 < 0.50)
)s
having count(*) > 5
comment le faire retourner 0 si aucune valeur n'est disponible?
sql
postgresql
Andrew
la source
la source
from web_price_scan
sont des sélections distinctes; ne sais pas quel est le problème ici?having
clause sans agroup by
(qui par défaut est un seul groupe). Il agit comme unewhere
clause sur les résultats agrégés. Dans ce cas, les lignes ne sont renvoyées que si plus de 5 lignes sont renvoyées par la sous-requête de 1er niveau.Réponses:
utiliser coalesce
Éditer
Voici un exemple de
COALESCE
avec votre requête:IMHO
COALESCE
ne doit pas être utilisé avecAVG
car il modifie la valeur.NULL
signifie inconnu et rien d'autre. Ce n'est pas comme l'utiliserSUM
. Dans cet exemple, si nous remplaçonsAVG
parSUM
, le résultat n'est pas déformé. Ajouter 0 à une somme ne fait de mal à personne, mais en calculant une moyenne avec 0 pour les valeurs inconnues, vous n'obtenez pas la moyenne réelle.Dans ce cas, je voudrais ajouter
price IS NOT NULL
à laWHERE
clause pour éviter ces valeurs inconnues.la source
from web_price_scan...
semble répété ...NULLIF(v1, v2)
fait à peu près le contraire deCOALESCE
en ce qu'il retourneNULL
siv1
égalv2
.(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 au 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, le second 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 il renverra NULL s'il n'y a rien à faire la moyenne. Cela a généralement du sens, car NULL doit être considéré comme "inconnu". Si vous souhaitez remplacer cela, vous pouvez utiliser coalesce (comme suggéré par Luc M).
bien sûr, "from foo" peut être remplacé par "from (... toute logique compliquée ici ...) as foo"
Maintenant, la ligne NULL du tableau doit-elle être comptée comme 0? Ensuite, la fusion doit être utilisée dans l'appel avg.
la source
Je peux penser à 2 façons d'y parvenir:
IFNULL ():
La fonction IFNULL () renvoie une valeur spécifiée si l'expression est NULL.Si l'expression est NOT NULL, cette fonction renvoie l'expression.
Syntaxe:
Exemple d'IFNULL () avec votre requête:
SE FONDRE()
La fonction COALESCE () renvoie la première valeur non nulle d'une liste.
Syntaxe:
Exemple de COALESCE () avec votre requête:
la source