2010-03-19 33 views
7

¿Hay alguna manera simple de excluir nulos que afecten a avg? Parecen contar como 0, que no es lo que quiero. Simplemente no quiero tomar en cuenta su promedio, sin embargo, aquí está el truco, no puedo soltarlos del conjunto de resultados, ya que ese registro tiene datos que necesito.MySQL: promediando con nulos

Actualización:

ejemplo:

select avg(col1+col2), count(col3) from table1 
where 
group by SomeArbitraryCol 
having avg(col1+col2) < 500 and count(col3) > 3 
order by avgcol1+col2) asc; 

Esto estaría trabajando para mí, pero los promedios no son exactos, ya que están contando los valores nulos como 0, lo que realmente está lanzando fuera de la promedio completo

+0

¿Qué idioma? ¿O estás haciendo esto todo en SQL? –

+0

SQL simple en MySQL – Zombies

+1

No lo obtuve, ¿por qué no seleccionar solo los registros con valores nulos y promediarlos? – questzen

Respuesta

13

Las funciones agregadas (SUMA, AVG, COUNT, etc.) en SQL siempre excluyen automáticamente NULL.

So SUM (col)/COUNT (col) = AVG (col): esto es genial y consistente.

El caso especial de COUNT (*) cuenta cada fila.

Si compone una expresión con NULLs: A + B donde A o B es NULL, entonces A + B será NULL independientemente de que la otra columna sea NULL.

Cuando hay valores NULL, en general, AVG (A + B) <> AVG (A) + AVG (B), y es probable que también tengan denominadores diferentes. Debería envolver las columnas: AVG (COALESCE (A, 0) + COALESCE (B, 0)) para resolver eso, pero quizás también excluya el caso donde COALESCE (A, 0) + COALESCE (B, 0).

Sobre la base de su código, sugeriría:

select avg(coalesce(col1, 0) + coalesce(col2, 0)), count(col3) from table1 
where coalesce(col1, col2) is not null -- double nulls are eliminated 
group by SomeArbitraryCol 
having avg(coalesce(col1, 0) + coalesce(col2, 0)) < 500 and count(col3) > 3 
order by avg(coalesce(col1, 0) + coalesce(col2, 0)) asc; 
5
AVG(number) 

Es la mejor manera que se me ocurre. Esto no debería incluir automáticamente los nulos. Here es una pequeña lectura.

+0

¿Es esto lo mismo para number1 + number2? Como no estoy obteniendo eso, para mí los nulos parecen estar contando como 0, lo que pesa demasiado sobre el promedio. – Zombies

+0

@Zombies No, no es lo mismo para una expresión de adición manual que sigue las reglas NULL normales. –

3
SELECT SUM(field)/COUNT(field) 
FROM table 
WHERE othercondition AND (field IS NOT NULL) 

Link

+0

¿No dejará esto las columnas donde el campo es nulo? Necesito ese col sin embargo, que es lo que hace esto complicado. – Zombies

+1

AVG (col) siempre es equivalente a SUM (col)/COUNT (col), y los NULL se excluyen automáticamente, por lo que esta consulta siempre devolverá los mismos resultados que SELECT AVG (campo) FROM table DONDE otra condición. –

1

respuesta en base a la pregunta original:

SELECT AVG(t1.NumCol + t1.NumCol2), COUNT(table.NumCol) 
FROM 
(
SELECT NumCol, NumCol2 
FROM table 
WHERE (cond) AND (NumCol IS NOT NULL) AND (NumCol2 IS NOT NULL) 
) t1, 
table 
WHERE (cond) 

Creo que con las nuevas restricciones, esto todavía funciona en teoría, pero no es la manera más eficiente

1

hay una buena probabilidad de que usted será capaz de llegar a la respuesta correcta de lo que otros han dicho aquí, pero en caso de que no tienen:

¿Qué valores en su tabla PUEDEN SER NULOS? ¿Y qué quieres que suceda si alguno de ellos es?

Nunca se especifica qué resultados quiere ver si es NULL col1, col2 o es NULL, o si tanto resultan ser NULL, etc.

0

recientemente he utilizado este truco:

AVG(
    CASE 
     WHEN 
      valToBeAveraged IS NULL 
     THEN 
      0 
     ELSE 
      valToBeAveraged 
    END 
) 

Creo que la advertencia es solo eso. Pero esto me da tranquilidad porque sé exactamente cómo funciona.

Código feliz