sql >> Base de Datos >  >> RDS >> Mysql

cómo obtener una tendencia superior con avg mysql

Lo que parece querer aquí es el promedio móvil de M registros anteriores a partir del registro actual y debemos seleccionar el registro actual si el valor de la columna del registro actual es mayor que el promedio móvil.

Aquí está mi intento:

SET @M := 2;

SELECT * FROM
(
  SELECT (@rownumber:= @rownumber + 1) AS rn, yt.*
  FROM your_table yt,(SELECT @rownumber:= 0) nums
  ORDER BY name, id
) a
WHERE a.var1 > 
(
    SELECT avg(b.var1)
    FROM
    (
      SELECT (@rownumber:= @rownumber + 1) AS rn, yt.*
      FROM your_table yt,(SELECT @rownumber:= 0) nums
      ORDER BY name, id
    ) b
    WHERE b.rn > a.rn - @M AND b.rn <= a.rn 
)

@M es el conteo de registros pasados ​​que se considerarán para encontrar el promedio móvil.

Aquí está el código en SQL Fiddle

[EDITAR]:

Aquí hay otra solución que, según yo, debería ser más eficiente que la consulta correlacionada.

SET @M := 2;

 SELECT a.* FROM
 ( 
  SELECT (@rownumber:= @rownumber + 1) AS rn, yt.*
      FROM your_table yt,(SELECT @rownumber:= 0) nums
      ORDER BY name, id
 ) a
 JOIN 
 (
    SELECT b.name, b.rn, AVG(c.var1) AS av
    FROM
    (
      SELECT (@rownumber1:= @rownumber1 + 1) AS rn, yt.*
      FROM your_table yt,(SELECT @rownumber1:= 0) nums
      ORDER BY name, id
    ) b
    JOIN
    (
      SELECT (@rownumber2:= @rownumber2 + 1) AS rn, yt.*
      FROM your_table yt,(SELECT @rownumber2:= 0) nums
      ORDER BY name, id
    ) c
    ON b.name = c.name
    AND c.rn > (b.rn - @M) AND c.rn <= b.rn
    GROUP BY b.name,b.rn
 ) runningavg 
 ON a.name = runningavg.name
 AND a.rn = runningavg.rn
 AND a.var1 > runningavg.av

Aquí he usado inner join simple para calcular el promedio móvil y nuevamente con la unión interna, ha seleccionado filas que tienen un valor de columna mayor que el promedio.

Aquí está el código en SQL Fiddle

Déjame saber si resultó ser eficiente.