web-dev-qa-db-fra.com

Obtenir AVG en ignorant les valeurs Null ou Zero

Comment puis-je obtenir le AVG d'une colonne en ignorant les valeurs NULL et zéro?

J'ai trois colonnes pour obtenir leur moyenne, j'essaie d'utiliser le script suivant:

SELECT distinct
     AVG(cast(ISNULL(a.SecurityW,0) as bigint)) as Average1
     ,AVG(cast(ISNULL(a.TransferW,0) as bigint)) as Average2
     ,AVG(cast(ISNULL(a.StaffW,0) as bigint)) as Average3
FROM Table1 a,  Table2 b
WHERE a.SecurityW <> 0 AND a.SecurityW IS NOT NULL
AND a.TransferW<> 0 AND a.TransferWIS NOT NULL
AND a.StaffW<> 0 AND a.StaffWIS NOT NULL
AND MONTH(a.ActualTime) = 4
AND YEAR(a.ActualTime) = 2013

Je n'obtiens aucun résultat, cependant les trois colonnes ont des valeurs incluant NULL et zéros!

Est-il possible d'exclure des valeurs nulles avant d'obtenir la moyenne?

exemple: AVERAGE(NOTNULL(SecurityW))

35
SVI

NULL est déjà ignoré, vous pouvez donc utiliser NULLIF pour activer 0 à NULL. De plus, vous n'avez pas besoin de DISTINCT et votre WHERE sur ActualTime n'est pas sargable.

SELECT AVG(cast(NULLIF(a.SecurityW, 0) AS BIGINT)) AS Average1,
       AVG(cast(NULLIF(a.TransferW, 0) AS BIGINT)) AS Average2,
       AVG(cast(NULLIF(a.StaffW, 0) AS BIGINT))    AS Average3
FROM   Table1 a
WHERE  a.ActualTime >= '20130401'
       AND a.ActualTime < '20130501' 

PS je n'ai aucune idée de ce que Table2 b est dans la requête d'origine car il n'y a pas de condition de jointure, donc je l'ai omis de ma réponse.

59
Martin Smith

cela devrait marcher, je n'ai pas essayé. cela exclura zéro. NULL est exclu par défaut

AVG (CASE WHEN SecurityW <> 0 THEN SecurityW ELSE NULL END)
12
chetan

En cas de ne pas considérer '0' ou 'NULL' dans la fonction moyenne. Simplement utiliser

AVG(NULLIF(your_column_name,0))
4
Irfan

a travaillé pour moi :

AVG(CASE WHEN SecurityW <> 0 THEN SecurityW ELSE NULL END)
3
Emmerich Liang

Vous tentez déjà de filtrer les valeurs NULL avec NOT NULL. J'ai changé ceci en IS NOT NULL dans la clause WHERE afin qu’elle s’exécute. Nous pouvons le refactoriser en supprimant la fonction ISNULL de la méthode AVG. De plus, je doute que vous ayez réellement besoin de bigint pour pouvoir supprimer le casting.

SELECT distinct
     AVG(a.SecurityW) as Average1
     ,AVG(a.TransferW) as Average2
     ,AVG(a.StaffW) as Average3
FROM Table1 a,  Table2 b
WHERE a.SecurityW <> 0 AND a.SecurityW IS NOT NULL
AND a.TransferW<> 0 AND a.TransferWIS IS NOT NULL
AND a.StaffW<> 0 AND a.StaffWIS IS NOT NULL
AND MONTH(a.ActualTime) = 4
AND YEAR(a.ActualTime) = 2013
1
Darren