sql >> データベース >  >> RDS >> Mysql

avgmysqlで上位トレンドを取得する方法

    ここで必要と思われるのは、現在のレコードから始まる過去のMレコードの移動平均であり、現在のレコードの列の値が現在のレコードよりも大きい場合は、現在のレコードを選択する必要があります。

    これが私の試みです:

    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は、移動平均を見つけるために考慮される過去のレコードの数です。

    SQLFiddle のコードは次のとおりです。

    [編集]:

    これは、私によれば、相関クエリよりも効率的であるはずの別のソリューションです。

    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
    

    ここでは、単純なinner joinを使用しました 移動平均を計算し、内部結合を使用して、列の値が平均よりも大きい行を選択しました。

    SQLFiddle のコードは次のとおりです。

    効率的であることが証明されたかどうか教えてください。




    1. SQLの行を列に転置する

    2. Mysqlの遅いクエリ:INNER JOIN +ORDERBYによりファイルソートが発生します

    3. MySQLでランクを計算する方法

    4. MySQLおよびJDBCを使用した複数のステートメントによるトリガーの構文例外