Tengo una gran tabla (de sitios) con varias columnas numéricas, por ejemplo, a través de f. (Estas son clasificaciones de sitios de diferentes organizaciones, como alexa, google, quantcast, etc. Cada una tiene un rango y formato diferente; son descargas directas desde las DB externas).mysql: Promedio sobre varias columnas en una fila, ignorando nulos
Para muchos de los registros, uno o más de estas columnas es nulo, porque el DB externo no tiene datos para él. Todos cubren diferentes subconjuntos de mi DB.
Quiero que la columna t sea su promedio ponderado (cada uno de ... f tiene pesos estáticos que asigno), ignorando los valores nulos (que pueden ocurrir en cualquiera de ellos), excepto que son nulos si son todos nulos .
Preferiría hacer esto con un simple cálculo de SQL, en lugar de hacerlo en el código de la aplicación o usar un gran bloque anidado feo para manejar cada permutación de nulos. (Dado que tengo un número creciente de columnas para promediar a medida que agrego más fuentes de DB externas, esto sería exponencialmente más feo y propenso a errores.)
Usaría AVG pero eso es solo para grupos, y esto es w/en un registro. Los datos son semánticamente anulables, y no quiero promediar en algún valor "promedio" en lugar de los nulos; Solo quiero contar las columnas para las que hay datos.
¿Hay una buena manera de hacerlo?
Idealmente, lo que quiero es algo así como UPDATE sites SET t = AVG(a*@a_weight,b*@b_weight,...)
donde los valores nulos simplemente se ignoran y no se produce ninguna agrupación.
EDIT: Lo que terminé usando, basada en la furgoneta de la adición y en los promedios ponderados correctos (suponiendo que a
ya se ha normalizado, según sea necesario, en este caso a un flotador 0-1 (1 = mejor):
UPDATE sites
SET t = (@a_weight * IFNULL(a, 0) + ...)/(IF(a IS NULL, 0, @a_weight) + ...)
WHERE (IF(a IS NULL, 0, 1) + ...) > 0
Creo que IFNULL es una alternativa más clara que COALESCE, pero es equivalente. IF (a IS NULL, 0,1) es similarmente más simple que tu CASE. De lo contrario, creo que esto hace todo lo que quería, básicamente estás poniendo a cero las columnas nulas y quitándola del denominador, lo cual es lo más inteligente y algo en lo que debería haber pensado. :-PAG – Sai